-
Language:
English
-
Language:
English
8.2. Listener Notifications
Each cache event triggers a notification that is dispatched to listeners. A listener is a simple POJO annotated with
@Listener
. A Listenable is an interface that denotes that the implementation can have listeners attached to it. Each listener is registered using methods defined in the Listenable.
A listener can be attached to both the cache and Cache Manager to allow them to receive cache-level or cache manager-level notifications.
8.2.1. About Cache-level Notifications
In Red Hat JBoss Data Grid, cache-level events occur on a per-cache basis. Examples of cache-level events include the addition, removal and modification of entries, which trigger notifications to listeners registered on the relevant cache.
8.2.2. Cache Manager-level Notifications
Examples of events that occur in Red Hat JBoss Data Grid at the cache manager-level are:
- The starting and stopping of caches
- Nodes joining or leaving a cluster;
Cache manager-level events are located globally and used cluster-wide, but are restricted to events within caches created by a single cache manager.
The first two types of events,
CacheStarted
and CacheStopped
are highly similar, and the following example demonstrates printing out the name of the cache that has started or stopped:
@CacheStarted public void cacheStarted(CacheStartedEvent event){ // Print the name of the Cache that started log.info("Cache Started: " + event.getCacheName()); } @CacheStopped public void cacheStopped(CacheStoppedEvent event){ // Print the name of the Cache that stopped log.info("Cache Stopped: " + event.getCacheName()); }
When receiving a
ViewChangedEvent
or MergeEvent
note that the list of old and new members is from the node that generated the event. For instance, consider the following scenario:
- A JDG Cluster currently consists of nodes A, B, and C.
- Node D joins the cluster.
- Nodes A, B, and C will receive a
ViewChangedEvent
with [A,B,C] as the list of old members, and [A,B,C,D] as the list of new members. - Node D will receive a
ViewChangedEvent
with [D] as the list of old members, and [A,B,C,D] as the list of new members.
Therefore, a set intersection may be used to determine if a node has recently joined or left a cluster. By using
getOldMembers()
in conjunction with getNewMembers()
, we may determine the set of nodes that have joined or left the cluster, as seen below:
@ViewChanged public void viewChanged(ViewChangedEvent event){ HashSet<Address> oldMembers = new HashSet(event.getOldMembers()); HashSet<Address> newMembers = new HashSet(event.getNewMembers()); HashSet<Address> oldCopy = (HashSet<Address>)oldMembers.clone(); // Remove all new nodes from the old view. // The resulting set indicates nodes that have left the cluster. oldCopy.removeAll(newMembers); if(oldCopy.size() > 0){ for (Address oldAdd : oldCopy){ log.info("Node left:" + oldAdd.toString()); } } // Remove all old nodes from the new view. // The resulting set indicates nodes that have joined the cluster. newMembers.removeAll(oldMembers); if(newMembers.size() > 0){ for(Address newAdd : newMembers){ log.info("Node joined: " + newAdd.toString()); } } }
Similar logic may be used during a
MergeEvent
to determine the new set of members in the cluster.
8.2.3. About Synchronous and Asynchronous Notifications
By default, notifications in Red Hat JBoss Data Grid are dispatched in the same thread that generates the event. Therefore the listener must be written in a way that does not block or prevent the thread's progression.
Alternatively, the listener can be annotated as asynchronous, which dispatches notifications in a separate thread and prevents blocking the operations of the original thread.
Annotate listeners using the following:
@Listener (sync = false) public class MyAsyncListener { .... }
Use the
<asyncListenerExecutor/>
element in the configuration file to tune the thread pool that is used to dispatch asynchronous notifications.
Important
When using a synchronous, non-clustered listener that handles the
CacheEntryExpiredEvent
ensure that this listener does not block execution, as the expiration reaper is also synchronous in a non-clustered environment.