akka.contrib.pattern
Class ClusterSingletonManager

java.lang.Object
  extended by akka.contrib.pattern.ClusterSingletonManager
All Implemented Interfaces:
Actor, ActorLogging, FSM<ClusterSingletonManager.State,ClusterSingletonManager.Data>, Listeners

public class ClusterSingletonManager
extends java.lang.Object
implements Actor, FSM<ClusterSingletonManager.State,ClusterSingletonManager.Data>

Manages a cluster wide singleton actor instance, i.e. at most one singleton instance is running at any point in time. The ClusterSingletonManager is supposed to be started on all nodes in the cluster with actorOf. The actual singleton is started on the leader node of the cluster by creating a child actor from the supplied singletonProps.

The singleton actor is always running on the leader member, which is nothing more than the address currently sorted first in the member ring. This can change when adding or removing members. A graceful hand over can normally be performed when joining a new node that becomes leader or removing current leader node. Be aware that there is a short time period when there is no active singleton during the hand-over process.

The singleton actor can at any time send a message to its parent ClusterSingletonManager and this message will be passed to the singletonProps factory on the new leader node when a graceful hand-over is performed.

The cluster failure detector will notice when a leader node becomes unreachable due to things like JVM crash, hard shut down, or network failure. Then a new leader node will take over and a new singleton actor is created. For these failure scenarios there will not be a graceful hand-over, but more than one active singletons is prevented by all reasonable means. Some corner cases are eventually resolved by configurable timeouts.

You access the singleton actor with actorFor using the names you have specified when creating the ClusterSingletonManager. You can subscribe to ClusterEvent.LeaderChanged to keep track of which node it is supposed to be running on. Alternatively the singleton actor may broadcast its existence when it is started.

==Arguments==

'''''singletonProps''''' Factory for Props of the singleton actor instance. The Option parameter is the the handOverData sent from previous singleton. handOverData might be None when no hand-over took place, or when the there is no need for sending data to the new singleton. The handOverData is typically passed as parameter to the constructor of the singleton actor.

'''''singletonName''''' The actor name of the child singleton actor.

'''''terminationMessage''''' When handing over to a new leader node this terminationMessage is sent to the singleton actor to tell it to finish its work, close resources, and stop. It can sending a message back to the parent ClusterSingletonManager, which will passed to the singletonProps factory on the new leader node. The hand-over to the new leader node is completed when the singleton actor is terminated. Note that PoisonPill is a perfectly fine terminationMessage if you only need to stop the actor.

'''''maxHandOverRetries''''' When a node is becoming leader it sends hand-over request to previous leader. This is retried with the retryInterval until the previous leader confirms that the hand over has started, or this maxHandOverRetries limit has been reached. If the retry limit is reached it takes the decision to be the new leader if previous leader is unknown (typically removed or downed), otherwise it initiates a new round by throwing ClusterSingletonManagerIsStuck and expecting restart with fresh state. For a cluster with many members you might need to increase this retry limit because it takes longer time to propagate changes across all nodes.

'''''maxTakeOverRetries''''' When a leader node is not leader any more it sends take over request to the new leader to initiate the normal hand-over process. This is especially useful when new node joins and becomes leader immediately, without knowing who was previous leader. This is retried with the retryInterval until this retry limit has been reached. If the retry limit is reached it initiates a new round by throwing ClusterSingletonManagerIsStuck and expecting restart with fresh state. This will also cause the singleton actor to be stopped. maxTakeOverRetries must be less than maxHandOverRetries to ensure that new leader doesn't start singleton actor before previous is stopped for certain corner cases.

'''''loggingEnabled''''' Logging of what is going on at info log level.


Nested Class Summary
static interface ClusterSingletonManager.Data
          Internal API public due to the with FSM type parameters
static interface ClusterSingletonManager.State
          Internal API public due to the with FSM type parameters
 
Nested classes/interfaces inherited from interface akka.actor.Actor
Actor.emptyBehavior$
 
Nested classes/interfaces inherited from interface akka.actor.FSM
FSM.$minus$greater$, FSM.CurrentState<S>, FSM.CurrentState$, FSM.Event, FSM.Event$, FSM.Failure, FSM.Failure$, FSM.LogEntry<S,D>, FSM.LogEntry$, FSM.Normal$, FSM.NullFunction$, FSM.Reason, FSM.Shutdown$, FSM.State$, FSM.StateTimeout$, FSM.StopEvent, FSM.StopEvent$, FSM.SubscribeTransitionCallBack, FSM.SubscribeTransitionCallBack$, FSM.TransformHelper, FSM.Transition<S>, FSM.Transition$, FSM.UnsubscribeTransitionCallBack, FSM.UnsubscribeTransitionCallBack$
 
Constructor Summary
ClusterSingletonManager(scala.Function1<scala.Option<java.lang.Object>,Props> singletonProps, java.lang.String singletonName, java.lang.Object terminationMessage, int maxHandOverRetries, int maxTakeOverRetries, scala.concurrent.duration.FiniteDuration retryInterval, boolean loggingEnabled)
           
ClusterSingletonManager(java.lang.String singletonName, java.lang.Object terminationMessage, ClusterSingletonPropsFactory singletonPropsFactory)
          Java API constructor with default values.
ClusterSingletonManager(java.lang.String singletonName, java.lang.Object terminationMessage, int maxHandOverRetries, int maxTakeOverRetries, scala.concurrent.duration.FiniteDuration retryInterval, boolean loggingEnabled, ClusterSingletonPropsFactory singletonPropsFactory)
          Full Java API constructor.
 
Method Summary
 void addDowned(Address address)
           
 void addRemoved(Address address)
           
 void cleanupOverdueNotMemberAnyMore()
           
 Cluster cluster()
           
 scala.collection.immutable.Map<Address,scala.concurrent.duration.Deadline> downed()
           
 void getNextLeaderChanged()
           
 FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> gotoHandingOver(ActorRef singleton, boolean singletonTerminated, scala.Option<java.lang.Object> handOverData, scala.Option<ActorRef> handOverTo)
           
 FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> gotoLeader(scala.Option<java.lang.Object> handOverData)
           
 FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> handOverDone(scala.Option<ActorRef> handOverTo, scala.Option<java.lang.Object> handOverData)
           
 ActorRef leaderChangedBuffer()
           
 boolean leaderChangedReceived()
           
 void logInfo(java.lang.String message)
           
 void logInfo(java.lang.String template, java.lang.Object arg1)
           
 void logInfo(java.lang.String template, java.lang.Object arg1, java.lang.Object arg2)
           
 ActorRef peer(Address at)
           
 void postStop()
          User overridable callback.
 void preStart()
          User overridable callback.
 scala.collection.immutable.Map<Address,scala.concurrent.duration.Deadline> removed()
           
 scala.Some<Address> selfAddressOption()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface akka.actor.Actor
context, noSender, postRestart, preRestart, receive, self, sender, supervisorStrategy, unhandled
 
Methods inherited from interface akka.actor.FSM
applyState, cancelTimer, currentState, debugEvent, generation, handleEvent, handleEventDefault, handleTransition, initialize, makeTransition, nextState, nextStateData, onTermination, onTransition, processEvent, processMsg, receive, register, setStateTimeout, setTimer, startWith, stateData, stateFunctions, stateName, StateTimeout, stateTimeouts, stay, stop, stop, stop, terminate, terminateEvent, timeoutFuture, timerGen, timers, total2pf, transform, transitionEvent, when, whenUnhandled
 
Methods inherited from interface akka.routing.Listeners
gossip, listenerManagement, listeners
 
Methods inherited from interface akka.actor.ActorLogging
log
 

Constructor Detail

ClusterSingletonManager

public ClusterSingletonManager(scala.Function1<scala.Option<java.lang.Object>,Props> singletonProps,
                               java.lang.String singletonName,
                               java.lang.Object terminationMessage,
                               int maxHandOverRetries,
                               int maxTakeOverRetries,
                               scala.concurrent.duration.FiniteDuration retryInterval,
                               boolean loggingEnabled)

ClusterSingletonManager

public ClusterSingletonManager(java.lang.String singletonName,
                               java.lang.Object terminationMessage,
                               int maxHandOverRetries,
                               int maxTakeOverRetries,
                               scala.concurrent.duration.FiniteDuration retryInterval,
                               boolean loggingEnabled,
                               ClusterSingletonPropsFactory singletonPropsFactory)
Full Java API constructor.


ClusterSingletonManager

public ClusterSingletonManager(java.lang.String singletonName,
                               java.lang.Object terminationMessage,
                               ClusterSingletonPropsFactory singletonPropsFactory)
Java API constructor with default values.

Method Detail

cluster

public Cluster cluster()

selfAddressOption

public scala.Some<Address> selfAddressOption()

leaderChangedBuffer

public ActorRef leaderChangedBuffer()

leaderChangedReceived

public boolean leaderChangedReceived()

downed

public scala.collection.immutable.Map<Address,scala.concurrent.duration.Deadline> downed()

removed

public scala.collection.immutable.Map<Address,scala.concurrent.duration.Deadline> removed()

addDowned

public void addDowned(Address address)

addRemoved

public void addRemoved(Address address)

cleanupOverdueNotMemberAnyMore

public void cleanupOverdueNotMemberAnyMore()

logInfo

public void logInfo(java.lang.String message)

logInfo

public void logInfo(java.lang.String template,
                    java.lang.Object arg1)

logInfo

public void logInfo(java.lang.String template,
                    java.lang.Object arg1,
                    java.lang.Object arg2)

preStart

public void preStart()
Description copied from interface: Actor
User overridable callback.

Is called when an Actor is started. Actors are automatically started asynchronously when created. Empty default implementation.

Specified by:
preStart in interface Actor

postStop

public void postStop()
Description copied from interface: Actor
User overridable callback.

Is called asynchronously after 'actor.stop()' is invoked. Empty default implementation.

Specified by:
postStop in interface Actor
Specified by:
postStop in interface FSM<ClusterSingletonManager.State,ClusterSingletonManager.Data>

peer

public ActorRef peer(Address at)

getNextLeaderChanged

public void getNextLeaderChanged()

gotoLeader

public FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> gotoLeader(scala.Option<java.lang.Object> handOverData)

gotoHandingOver

public FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> gotoHandingOver(ActorRef singleton,
                                                                                             boolean singletonTerminated,
                                                                                             scala.Option<java.lang.Object> handOverData,
                                                                                             scala.Option<ActorRef> handOverTo)

handOverDone

public FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> handOverDone(scala.Option<ActorRef> handOverTo,
                                                                                          scala.Option<java.lang.Object> handOverData)