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 singleton actor instance among all cluster nodes or a group of nodes tagged with a specific role. At most one singleton instance is running at any point in time.

The ClusterSingletonManager is supposed to be started on all nodes, or all nodes with specified role, in the cluster with actorOf. The actual singleton is started on the oldest node by creating a child actor from the supplied singletonProps.

The singleton actor is always running on the oldest member, which can be determined by Member.isOlderThan(akka.cluster.Member). This can change when removing members. A graceful hand over can normally be performed when current oldest node is leaving the cluster. 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 oldest node when a graceful hand-over is performed.

The cluster failure detector will notice when oldest node becomes unreachable due to things like JVM crash, hard shut down, or network failure. Then a new oldest 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 actorSelection using the names you have specified when creating the ClusterSingletonManager. You can subscribe to ClusterEvent.MemberEvent and sort the members by age (akka.cluster.ClusterEvent.Member#isOlderThan) to keep track of oldest member. Alternatively the singleton actor may broadcast its existence when it is started.

Use factory method ClusterSingletonManager#props] to create the {@link akka.actor.Props} for the actor.

==Arguments==

'''''singletonProps''''' Factory for {@link akka.actor.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. Note that the singletonProps function is applied when creating the singleton actor and it must not use members that are not thread safe, e.g. mutable state in enclosing actor.

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

'''''terminationMessage''''' When handing over to a new oldest 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 oldest node. The hand-over to the new oldest node is completed when the singleton actor is terminated. Note that {@link akka.actor.PoisonPill} is a perfectly fine terminationMessage if you only need to stop the actor.

'''''role''''' Singleton among the nodes tagged with specified role. If the role is not specified it's a singleton among all nodes in the cluster.

'''''maxHandOverRetries''''' When a node is becoming oldest it sends hand-over request to previous oldest. This is retried with the retryInterval until the previous oldest 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 oldest if previous oldest is unknown (typically removed), otherwise it initiates a new round by throwing {@link akka.contrib.pattern.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 oldest node is not oldest any more it sends take over request to the new oldest to initiate the normal hand-over process. This is especially useful when new node joins and becomes oldest immediately, without knowing who was previous oldest. 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 {@link akka.contrib.pattern.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 oldest doesn't start singleton actor before previous is stopped for certain corner cases.


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.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$
 
Nested classes/interfaces inherited from interface akka.actor.Actor
Actor.emptyBehavior$
 
Constructor Summary
ClusterSingletonManager(scala.Function1<scala.Option<java.lang.Object>,Props> singletonProps, java.lang.String singletonName, java.lang.Object terminationMessage, scala.Option<java.lang.String> role, int maxHandOverRetries, int maxTakeOverRetries, scala.concurrent.duration.FiniteDuration retryInterval)
           
 
Method Summary
 void addRemoved(Address address)
           
 void cleanupOverdueNotMemberAnyMore()
           
 Cluster cluster()
           
static Props defaultProps(java.lang.String singletonName, java.lang.Object terminationMessage, java.lang.String role, ClusterSingletonPropsFactory singletonPropsFactory)
          Java API: Factory method for ClusterSingletonManager Props with default values.
 void getNextOldestChanged()
           
 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> gotoOldest(scala.Option<java.lang.Object> handOverData)
           
 FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> handOverDone(scala.Option<ActorRef> handOverTo, scala.Option<java.lang.Object> handOverData)
           
 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 oldestChangedBuffer()
           
 boolean oldestChangedReceived()
           
 ActorSelection peer(Address at)
           
 void postStop()
          User overridable callback.
 void preStart()
          User overridable callback.
static Props props(scala.Function1<scala.Option<java.lang.Object>,Props> singletonProps, java.lang.String singletonName, java.lang.Object terminationMessage, scala.Option<java.lang.String> role, int maxHandOverRetries, int maxTakeOverRetries, scala.concurrent.duration.FiniteDuration retryInterval)
          Scala API: Factory method for ClusterSingletonManager Props.
static Props props(java.lang.String singletonName, java.lang.Object terminationMessage, java.lang.String role, int maxHandOverRetries, int maxTakeOverRetries, scala.concurrent.duration.FiniteDuration retryInterval, ClusterSingletonPropsFactory singletonPropsFactory)
          Java API: Factory method for ClusterSingletonManager Props.
 scala.collection.immutable.Map<Address,scala.concurrent.duration.Deadline> removed()
           
 scala.Some<Address> selfAddressOption()
           
 boolean selfExited()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface akka.actor.FSM
applyState, cancelTimer, currentState, debugEvent, generation, handleEvent, handleEventDefault, handleTransition, initialize, isStateTimerActive, isTimerActive, logTermination, 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.actor.Actor
context, noSender, postRestart, preRestart, self, sender, supervisorStrategy, unhandled
 
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,
                               scala.Option<java.lang.String> role,
                               int maxHandOverRetries,
                               int maxTakeOverRetries,
                               scala.concurrent.duration.FiniteDuration retryInterval)
Method Detail

props

public static Props props(scala.Function1<scala.Option<java.lang.Object>,Props> singletonProps,
                          java.lang.String singletonName,
                          java.lang.Object terminationMessage,
                          scala.Option<java.lang.String> role,
                          int maxHandOverRetries,
                          int maxTakeOverRetries,
                          scala.concurrent.duration.FiniteDuration retryInterval)
Scala API: Factory method for ClusterSingletonManager Props. Note that the singletonProps function is applied when creating the singleton actor and it must not use members that are not thread safe, e.g. mutable state in enclosing actor.


props

public static Props props(java.lang.String singletonName,
                          java.lang.Object terminationMessage,
                          java.lang.String role,
                          int maxHandOverRetries,
                          int maxTakeOverRetries,
                          scala.concurrent.duration.FiniteDuration retryInterval,
                          ClusterSingletonPropsFactory singletonPropsFactory)
Java API: Factory method for ClusterSingletonManager Props. Note that the singletonPropsFactory is invoked when creating the singleton actor and it must not use members that are not thread safe, e.g. mutable state in enclosing actor.


defaultProps

public static Props defaultProps(java.lang.String singletonName,
                                 java.lang.Object terminationMessage,
                                 java.lang.String role,
                                 ClusterSingletonPropsFactory singletonPropsFactory)
Java API: Factory method for ClusterSingletonManager Props with default values. Note that the singletonPropsFactory is invoked when creating the singleton actor and it must not use members that are not thread safe, e.g. mutable state in enclosing actor.


cluster

public Cluster cluster()

selfAddressOption

public scala.Some<Address> selfAddressOption()

oldestChangedBuffer

public ActorRef oldestChangedBuffer()

oldestChangedReceived

public boolean oldestChangedReceived()

selfExited

public boolean selfExited()

removed

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

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 ActorSelection peer(Address at)

getNextOldestChanged

public void getNextOldestChanged()

gotoOldest

public FSM.State<ClusterSingletonManager.State,ClusterSingletonManager.Data> gotoOldest(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)