Top Description Inners Fields Constructors Methods
net.sf.ehcache.distribution

public Class RMIAsynchronousCacheReplicator

extends RMISynchronousCacheReplicator
Class Inheritance
Imports
net.sf.ehcache.CacheException, .Ehcache, .Element, .Status, java.lang.ref.SoftReference, java.rmi.UnmarshalException, java.util.ArrayList, .List, .Queue, java.util.concurrent.ConcurrentLinkedQueue, net.sf.ehcache.distribution.RmiEventMessage.RmiEventType, org.slf4j.LoggerFactory, .Logger

Listens to net.sf.ehcache.CacheManager and net.sf.ehcache.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 java.lang.ref.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.

Author
Greg Luck
Version
$Id: RMIAsynchronousCacheReplicator.java 10789 2018-04-26 02:08:13Z adahanne $

Nested and Inner Type Summary

Modifier and TypeClass and Description
private class
RMIAsynchronousCacheReplicator.ReplicationThread

A background daemon thread that writes objects to the file.

Field Summary

Modifier and TypeField and Description
private static final Logger
private final int
maximumBatchSize

The maximum number of Element replication in single RMI message.

private final int
replicationInterval

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

private final Queue<Object>
replicationQueue

A queue of updates.

private final Thread
replicationThread

A thread which handles replication, so that replication can take place asynchronously and not hold up the cache

Inherited from net.sf.ehcache.distribution.RMISynchronousCacheReplicator:
replicatePutsreplicatePutsViaCopyreplicateRemovalsreplicateUpdatesreplicateUpdatesViaCopystatus

Constructor Summary

AccessConstructor and Description
public
RMIAsynchronousCacheReplicator(boolean replicatePuts, boolean replicatePutsViaCopy, boolean replicateUpdates, boolean replicateUpdatesViaCopy, boolean replicateRemovals, int replicationInterval, int maximumBatchSize)

Constructor for internal and subclass use

Method Summary

Modifier and TypeMethod and Description
protected void
addToReplicationQueue(RmiEventMessage eventMessage)

Adds a message to the queue.

public Object

Returns:

a clone
clone
()

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.clone.

Implements net.sf.ehcache.event.CacheEventListener.clone.

Creates a clone of this listener.
public final void
dispose()

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.dispose.

Implements net.sf.ehcache.event.CacheEventListener.dispose.

Give the replicator a chance to flush the replication queue, then cleanup and free resources when no longer needed
private List<EventMessage>

Returns:

a list of EventMessages which were able to be resolved
extractEventMessages
(int limit)

Extracts CacheEventMessages and attempts to get a hard reference to the underlying EventMessage

If an EventMessage has been invalidated due to SoftReference collection of the Element, it is not propagated.

private void
public final void
notifyElementPut(final Ehcache
the cache emitting the notification
cache
,
final Element
the element which was just put into the cache.
element
)

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementPut.

Implements net.sf.ehcache.event.CacheEventListener.notifyElementPut.

Called immediately after an element has been put into the cache.
public final void
notifyElementRemoved(final Ehcache
the cache emitting the notification
cache
,
final Element
the element just deleted, or a synthetic element with just the key set if no element was removed.
element
)

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementRemoved.

Implements net.sf.ehcache.event.CacheEventListener.notifyElementRemoved.

Called immediately after an attempt to remove an element.
public final void
notifyElementUpdated(final Ehcache
the cache emitting the notification
cache
,
final Element
the element which was just put into the cache.
element
)

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementUpdated.

Implements net.sf.ehcache.event.CacheEventListener.notifyElementUpdated.

Called immediately after an element has been put into the cache and the element already existed in the cache.
public void
notifyRemoveAll(final Ehcache
the cache emitting the notification
cache
)

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyRemoveAll.

Implements net.sf.ehcache.event.CacheEventListener.notifyRemoveAll.

Called during net.sf.ehcache.Ehcache#removeAll() to indicate that the all elements have been removed from the cache in a bulk operation.
private void
replicationThreadMain()

RemoteDebugger method for the replicationQueue thread.

private void
Inherited from net.sf.ehcache.distribution.RMISynchronousCacheReplicator:
aliveisReplicateUpdatesViaCopylistRemoteCachePeersnotAlivenotifyElementEvictednotifyElementExpiredreplicatePutNotificationreplicateRemovalNotificationreplicateRemoveAllNotification

Field Detail

LOGback to summary
private static final Logger LOG

Hides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.LOG.

maximumBatchSizeback to summary
private final int maximumBatchSize

The maximum number of Element replication in single RMI message.

replicationIntervalback to summary
private final int replicationInterval

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

replicationQueueback to summary
private final Queue<Object> replicationQueue

A queue of updates.

replicationThreadback to summary
private final Thread replicationThread

A thread which handles replication, so that replication can take place asynchronously and not hold up the cache

Constructor Detail

RMIAsynchronousCacheReplicatorback to summary
public RMIAsynchronousCacheReplicator(boolean replicatePuts, boolean replicatePutsViaCopy, boolean replicateUpdates, boolean replicateUpdatesViaCopy, boolean replicateRemovals, int replicationInterval, int maximumBatchSize)

Constructor for internal and subclass use

Method Detail

addToReplicationQueueback to summary
protected void addToReplicationQueue(RmiEventMessage eventMessage)

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.

cloneback to summary
public Object clone() throws CloneNotSupportedException

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.clone.

Implements net.sf.ehcache.event.CacheEventListener.clone.

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.

Returns:Object

a clone

Exceptions
CloneNotSupportedException:
if the listener could not be cloned.
disposeback to summary
public final void dispose()

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.dispose.

Implements net.sf.ehcache.event.CacheEventListener.dispose.

Give the replicator a chance to flush the replication queue, then cleanup and free resources when no longer needed

extractEventMessagesback to summary
private List<EventMessage> extractEventMessages(int limit)

Extracts CacheEventMessages and attempts to get a hard reference to the underlying EventMessage

If an EventMessage has been invalidated due to SoftReference collection of the Element, it is not propagated. This only affects puts and updates via copy.

Returns:List<EventMessage>

a list of EventMessages which were able to be resolved

flushReplicationQueueback to summary
private void flushReplicationQueue()
notifyElementPutback to summary
public final void notifyElementPut(final Ehcache cache, final Element element) throws CacheException

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementPut.

Implements net.sf.ehcache.event.CacheEventListener.notifyElementPut.

Doc from net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementPut.

Called immediately after an element has been put into the cache. The net.sf.ehcache.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.

Parameters
cache:Ehcache

the cache emitting the notification

element:Element

the element which was just put into the cache.

notifyElementRemovedback to summary
public final void notifyElementRemoved(final Ehcache cache, final Element element) throws CacheException

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementRemoved.

Implements net.sf.ehcache.event.CacheEventListener.notifyElementRemoved.

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.

Parameters
cache:Ehcache

the cache emitting the notification

element:Element

the element just deleted, or a synthetic element with just the key set if no element was removed.

notifyElementUpdatedback to summary
public final void notifyElementUpdated(final Ehcache cache, final Element element) throws CacheException

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyElementUpdated.

Implements net.sf.ehcache.event.CacheEventListener.notifyElementUpdated.

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 net.sf.ehcache.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.

Parameters
cache:Ehcache

the cache emitting the notification

element:Element

the element which was just put into the cache.

notifyRemoveAllback to summary
public void notifyRemoveAll(final Ehcache cache)

Overrides net.sf.ehcache.distribution.RMISynchronousCacheReplicator.notifyRemoveAll.

Implements net.sf.ehcache.event.CacheEventListener.notifyRemoveAll.

Called during net.sf.ehcache.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.

Parameters
cache:Ehcache

the cache emitting the notification

replicationThreadMainback to summary
private void replicationThreadMain()

RemoteDebugger method for the replicationQueue thread.

Note that the replicationQueue thread locks the cache for the entire time it is writing elements to the disk.

writeReplicationQueueback to summary
private void writeReplicationQueue()

Gets called once per replicationInterval.

Sends accumulated messages in bulk to each peer. i.e. if ther are 100 messages and 1 peer, 1 RMI invocation results, not 100. Also, if a peer is unavailable this is discovered in only 1 try.

Makes a copy of the queue so as not to hold up the enqueue operations.

Any exceptions are caught so that the replication thread does not die, and because errors are expected, due to peers becoming unavailable.

This method issues warnings for problems that can be fixed with configuration changes.

net.sf.ehcache.distribution back to summary

private final Class RMIAsynchronousCacheReplicator.ReplicationThread

extends Thread
Class Inheritance

A background daemon thread that writes objects to the file.

Field Summary

Inherited from java.lang.Thread:
MAX_PRIORITYMIN_PRIORITYNORM_PRIORITY

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public final void
run()

Overrides java.lang.Thread.run.

Implements java.lang.Runnable.run.

RemoteDebugger thread method.
Inherited from java.lang.Thread:
activeCountcheckAccessclonecountStackFramescurrentThreaddumpStackenumerategetAllStackTracesgetContextClassLoadergetDefaultUncaughtExceptionHandlergetIdgetNamegetPrioritygetStackTracegetStategetThreadGroupgetUncaughtExceptionHandlerholdsLockinterruptinterruptedisAliveisDaemonisInterruptedisVirtualjoinjoinjoinjoinofPlatformofVirtualonSpinWaitresumesetContextClassLoadersetDaemonsetDefaultUncaughtExceptionHandlersetNamesetPrioritysetUncaughtExceptionHandlersleepsleepsleepstartstartVirtualThreadstopsuspendthreadIdtoStringyield

Constructor Detail

ReplicationThreadback to summary
public ReplicationThread()

Method Detail

runback to summary
public final void run()

Overrides java.lang.Thread.run.

Implements java.lang.Runnable.run.

RemoteDebugger thread method.