Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: general edit for clarity

Geode provides APIs to capture a handful of events in such that a distributed system providing extensive documentation on how to implement listeners and callbacks for processing those can capture events, invoking callbacks to process those events either synchronously or asynchronously.

This document covers CacheWriter and CacheListener best practices for handlingCacheEventscovers best practices for the CacheWriter and the CacheListener.

Event Model

Cache Writers

CacheWriter is an event handler that synchronously handles “happens-before” events (CacheEvent) in an ordered fashion. It is mostly used for data validation and in some cases data invoked synchronously prior to an event. A cache writer is often used to validate data prior to an update of that data. It may also do a synchronization with external data sources, offering . This provides a write-through capability for regions handling events that can be local, within the same JVM, or remote, in the case of replicated or partitioned region.

Basic rules:

  • There can be only one CacheWriter per Regionregion.
  • For partitioned regions, only the writer in node that hosts the event’s primary node will process the eventbucket of the data will be the one that invokes the cache writer.
  • For replicated regions, only the first node to successfully execute the writer will process the event.
  • For local regions, only the local cache writer (if defined) will process the event.Unlike cache listeners, you can only install one cache writer in a region for each member.
  • CacheWriter can abort operations (fail-fast), and will propagate theCacheWriterException back CacheWriterException will propagate back to the caller.
  • Being a synchronous callback, it will block the current blocks the application's execution until it the handler completes.

Available CacheWriter events and callbacks:

Code Block
languagejava
beforeCreate(EntryEvent event)- Invoked before an entry is created.
beforeUpdate(EntryEvent event) - Invoked before an entry is updated.
beforeDestroy(EntryEvent event) - Invoked before an entry is destroyed.
beforeRegionClear(RegionEvent event) - Invoked before a region is cleared.
beforeRegionDestroy(RegionEvent event) - Invoked before a region is destroyed.

 

It is not recommended to perform long Because CacheWriter handlers are called synchronously, the application does not continue until the handler returns. Therefore, do not do long-running operations inside CacheWriter within the current threadhandler. If such a long-running operation is needed, consider processing it the operation asynchronously through an AsyncEventListener for example. Using an ExecutorServiceExecutorService to delegate that the execution to a different thread is possible, but considered it is an anti-pattern, since as it breaks no longer implements the fail-fast and happens-before concept of this callbackproperty, and the handling of the event is no longer synchronous, so its timing would not be guaranteed relative to the application's completion of the event.

Cache Listeners

CacheListener is an event handler that invoked synchronously responds to events after modifications occurred in the systemto a region occur. The main use cases for a CacheListener are synchronous write-behind and notifications, triggering actions after certain modifications occur on a region or on the system. It . The CacheListener can handle cache events related to entries (EntryEvent) and regions (RegionEvent), but events can be processed in a different order than the order they’re applied in in which they’ are applied to the region.

Basic rules:

  • You can install multiple CacheListener in handlers in the same region.
  • When multiple listeners are installed, they will be executed in the same order they’re registered in the system. One at a timethe handlers are invoked serially.  The invocation ordering is the same as the in which the listeners were registered.
  • For partitioned regions, only the listeners in the event’s primary node will process the event the node that hosts the primary bucket of the data will be the one that invokes the cache listeners.
  • For replicated regions, all nodes with the listener installed will process the event.
  • For local regions, only local listener listeners (if defined) will process the event.
  • For long running or batch processing, consider using an AsynchronousEventListener.
  • Being a synchronous callback, it will block the current execution until it the execution of each handler blocks the application's execution until the handler completes.

Available CacheListener events and callbacks:

Code Block
languagejava
afterCreate(EntryEvent<K,V> event) - HandlesInvoked theafter event ofa new key beingis added to a region
afterDestroy(EntryEvent<K,V> event) - Handles the event ofInvoked after an entry beingis destroyed
afterInvalidate(EntryEvent<K,V> event) - Handles the event ofInvoked after an entry's value beingis invalidated
afterRegionClear(RegionEvent<K,V> event) - Handles the event ofInvoked after a region beingis cleared
afterRegionCreate(RegionEvent<K,V> event) - Handles the event ofInvoked after a region beingis created
afterRegionDestroy(RegionEvent<K,V> event) - Handles the event ofInvoked after a region beingis destroyed
afterRegionInvalidate(RegionEvent<K,V> event) - Handles the event ofInvoked after a region beingis invalidated
afterRegionLive(RegionEvent<K,V> event) - Handles the event ofInvoked after a region beingbecomes live after receiving the marker from the server
afterUpdate(EntryEvent<K,V> event) - Handles the event ofInvoked after an entry's value beingis modified in a region
 

General recommendations

When dealing with Geode callbacks, there are some operations that should be avoided or used with extra attention. Some general recommendations are:

  • Do not perform distributed operations, such as using using the Distributed Lock service.
  • Avoid calling Region methods, particularly on non-colocated, partitioned regions.
  • Avoid calling functions through FunctionService, since they the function's execution can cause distributed deadlocksdeadlock.
  • Do not use any Geode APIs inside a CacheListener if you have conserve-sockets set to true.
  • Do not modify region attributes, since those messages will have priority and can cause blocks.
  • Avoid configurations where in which listeners or writers are deployed in a few nodes of the distributed system. Prefer a cluster-wide installation where every node can process the callback.
  • Any exceptions thrown are caught and logged, so users can troubleshoot using Geode logs.
  • EntryEvent.getNewValue() or EntryEvent.getOldValue() can result in deserializations, unless PDX and read-serialized=true are used.
  • Operations inside a CacheListener or a CacheWriter are thread-safe, and entries are locked for the current thread.

When using transactions:

  • A CacheWriter should not start transactions;.
  • Both CacheWriter and  and any CacheListener will receive all individual operations as part of a transaction, unlike their transactional counterparts TransactionWriter and and TransactionListener;.
  • When a rollback or commit happens, a CacheWriter can only be notified by aTransactionWriter, and should handle rollback or failures properly;.
  • CacheWriterException is still propagated to the application, and it should handle the failures in the context of the transaction by continuing or aborting; JTA is the recommended alternative.
  • In most cases when dealing with transactions, consider using a TransactionWriter, instead of a CacheWriter.
  • With global transactions, EntryEvent.getTransactionId() will return the current internal transaction ID.
  • Use the same transactional data source and make sure it’s it is JTA-enabled, so database operations inside a CacheWriter can be rolled back and participate in the same global transaction.

When dealing with transactions always consider using TransactionListener or or TransactionWriter for handling transaction events, but do notice that they’re they are cache-wide handlers.