ehcache

net.sf.ehcache.distribution
Class RMIAsynchronousCacheReplicator

java.lang.Object
  extended by net.sf.ehcache.distribution.RMISynchronousCacheReplicator
      extended by net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator
All Implemented Interfaces:
java.lang.Cloneable, CacheReplicator, CacheEventListener

public class RMIAsynchronousCacheReplicator
extends RMISynchronousCacheReplicator

Listens to CacheManager and Cache events and propagates those to CachePeer peers of the Cache asynchronously.

Updates are guaranteed to be replicated in the order in which they are received.

While much faster in operation than RMISynchronousCacheReplicator, it does suffer from a number of problems. Elements, which may be being spooled to DiskStore may stay around in memory because references are being held to them from EventMessages which are queued up. The replication thread runs once per second, limiting the build up. However a lot of elements can be put into a cache in that time. We do not want to get an OutOfMemoryError using distribution in circumstances when it would not happen if we were just using the DiskStore.

Accordingly, the Element values in EventMessages are held by SoftReference in the queue, so that they can be discarded if required by the GC to avoid an OutOfMemoryError. A log message will be issued on each flush of the queue if there were any forced discards. One problem with GC collection of SoftReferences is that the VM (JDK1.5 anyway) will do that rather than grow the heap size to the maximum. The workaround is to either set minimum heap size to the maximum heap size to force heap allocation at start up, or put up with a few lost messages while the heap grows.

Version:
$Id: RMIAsynchronousCacheReplicator.java 556 2007-10-29 02:06:30Z gregluck $
Author:
Greg Luck

Field Summary
protected  int asynchronousReplicationInterval
          The amount of time the replication thread sleeps after it detects the replicationQueue is empty before checking again.
protected  java.util.List replicationQueue
          A queue of updates.
protected  java.lang.Thread replicationThread
          A thread which handles replication, so that replication can take place asynchronously and not hold up the cache
 
Fields inherited from class net.sf.ehcache.distribution.RMISynchronousCacheReplicator
replicatePuts, replicateRemovals, replicateUpdates, replicateUpdatesViaCopy, status
 
Constructor Summary
RMIAsynchronousCacheReplicator(boolean replicatePuts, boolean replicateUpdates, boolean replicateUpdatesViaCopy, boolean replicateRemovals, int asynchronousReplicationInterval)
          Constructor for internal and subclass use
 
Method Summary
protected  void addToReplicationQueue(net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.CacheEventMessage cacheEventMessage)
          Adds a message to the queue.
 java.lang.Object clone()
          Creates a clone of this listener.
 void dispose()
          Give the replicator a chance to flush the replication queue, then cleanup and free resources when no longer needed
 void notifyElementPut(Ehcache cache, Element element)
          Called immediately after an element has been put into the cache.

This implementation queues the put notification for in-order replication to peers.

 void notifyElementRemoved(Ehcache cache, Element element)
          Called immediately after an attempt to remove an element.
 void notifyElementUpdated(Ehcache cache, Element element)
          Called immediately after an element has been put into the cache and the element already existed in the cache.
 void notifyRemoveAll(Ehcache cache)
          Called during Ehcache.removeAll() to indicate that the all elements have been removed from the cache in a bulk operation.
 
Methods inherited from class net.sf.ehcache.distribution.RMISynchronousCacheReplicator
alive, isReplicateUpdatesViaCopy, listRemoteCachePeers, notAlive, notifyElementEvicted, notifyElementExpired
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

replicationThread

protected java.lang.Thread replicationThread
A thread which handles replication, so that replication can take place asynchronously and not hold up the cache


asynchronousReplicationInterval

protected int asynchronousReplicationInterval
The amount of time the replication thread sleeps after it detects the replicationQueue is empty before checking again.


replicationQueue

protected final java.util.List replicationQueue
A queue of updates.

Constructor Detail

RMIAsynchronousCacheReplicator

public RMIAsynchronousCacheReplicator(boolean replicatePuts,
                                      boolean replicateUpdates,
                                      boolean replicateUpdatesViaCopy,
                                      boolean replicateRemovals,
                                      int asynchronousReplicationInterval)
Constructor for internal and subclass use

Parameters:
replicatePuts -
replicateUpdates -
replicateUpdatesViaCopy -
replicateRemovals -
asynchronousReplicationInterval -
Method Detail

notifyElementPut

public final void notifyElementPut(Ehcache cache,
                                   Element element)
                            throws CacheException
Called immediately after an element has been put into the cache. The Cache.put(net.sf.ehcache.Element) method will block until this method returns.

Implementers may wish to have access to the Element's fields, including value, so the element is provided. Implementers should be careful not to modify the element. The effect of any modifications is undefined.

This implementation queues the put notification for in-order replication to peers.

Specified by:
notifyElementPut in interface CacheEventListener
Overrides:
notifyElementPut in class RMISynchronousCacheReplicator
Parameters:
cache - the cache emitting the notification
element - the element which was just put into the cache.
Throws:
CacheException

notifyElementUpdated

public final void notifyElementUpdated(Ehcache cache,
                                       Element element)
                                throws CacheException
Called immediately after an element has been put into the cache and the element already existed in the cache. This is thus an update.

The Cache.put(net.sf.ehcache.Element) method will block until this method returns.

Implementers may wish to have access to the Element's fields, including value, so the element is provided. Implementers should be careful not to modify the element. The effect of any modifications is undefined.

Specified by:
notifyElementUpdated in interface CacheEventListener
Overrides:
notifyElementUpdated in class RMISynchronousCacheReplicator
Parameters:
cache - the cache emitting the notification
element - the element which was just put into the cache.
Throws:
CacheException

notifyElementRemoved

public final void notifyElementRemoved(Ehcache cache,
                                       Element element)
                                throws CacheException
Called immediately after an attempt to remove an element. The remove method will block until this method returns.

This notification is received regardless of whether the cache had an element matching the removal key or not. If an element was removed, the element is passed to this method, otherwise a synthetic element, with only the key set is passed in.

Specified by:
notifyElementRemoved in interface CacheEventListener
Overrides:
notifyElementRemoved in class RMISynchronousCacheReplicator
Parameters:
cache - the cache emitting the notification
element - the element just deleted, or a synthetic element with just the key set if no element was removed.
Throws:
CacheException

notifyRemoveAll

public void notifyRemoveAll(Ehcache cache)
Called during Ehcache.removeAll() to indicate that the all elements have been removed from the cache in a bulk operation. The usual notifyElementRemoved(net.sf.ehcache.Ehcache,net.sf.ehcache.Element) is not called.

This notification exists because clearing a cache is a special case. It is often not practical to serially process notifications where potentially millions of elements have been bulk deleted.

Specified by:
notifyRemoveAll in interface CacheEventListener
Overrides:
notifyRemoveAll in class RMISynchronousCacheReplicator
Parameters:
cache - the cache emitting the notification

addToReplicationQueue

protected void addToReplicationQueue(net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator.CacheEventMessage cacheEventMessage)
Adds a message to the queue.

This method checks the state of the replication thread and warns if it has stopped and then discards the message.

Parameters:
cacheEventMessage -

dispose

public final void dispose()
Give the replicator a chance to flush the replication queue, then cleanup and free resources when no longer needed

Specified by:
dispose in interface CacheEventListener
Overrides:
dispose in class RMISynchronousCacheReplicator

clone

public java.lang.Object clone()
                       throws java.lang.CloneNotSupportedException
Creates a clone of this listener. This method will only be called by ehcache before a cache is initialized.

This may not be possible for listeners after they have been initialized. Implementations should throw CloneNotSupportedException if they do not support clone.

Specified by:
clone in interface CacheEventListener
Overrides:
clone in class RMISynchronousCacheReplicator
Returns:
a clone
Throws:
java.lang.CloneNotSupportedException - if the listener could not be cloned.

ehcache