akka.actor
Interface FSM<S,D>

All Superinterfaces:
Actor, ActorLogging, Listeners
All Known Subinterfaces:
LoggingFSM<S,D>
All Known Implementing Classes:
AbstractFSM, AbstractLoggingFSM, BarrierCoordinator, ClientFSM, ClusterSingletonManager, ProtocolStateActor, ReliableProxy, ServerFSM, ThrottledAssociation, TimerBasedThrottler

public interface FSM<S,D>
extends Actor, Listeners, ActorLogging

Finite State Machine actor trait. Use as follows:

   object A {
     trait State
     case class One extends State
     case class Two extends State

     case class Data(i : Int)
   }

   class A extends Actor with FSM[A.State, A.Data] {
     import A._

     startWith(One, Data(42))
     when(One) {
         case Event(SomeMsg, Data(x)) => ...
         case Ev(SomeMsg) => ... // convenience when data not needed
     }
     when(Two, stateTimeout = 5 seconds) { ... }
     initialize()
   }
 

Within the partial function the following values are returned for effecting state transitions:

- stay for staying in the same state - stay using Data(...) for staying in the same state, but with different data - stay forMax 5.millis for staying with a state timeout; can be combined with using - goto(...) for changing into a different state; also supports using and forMax - stop for terminating this FSM actor

Each of the above also supports the method replying(AnyRef) for sending a reply before changing state.

While changing state, custom handlers may be invoked which are registered using onTransition. This is meant to enable concentrating different concerns in different places; you may choose to use when for describing the properties of a state, including of course initiating transitions, but you can describe the transitions using onTransition to avoid having to duplicate that code among multiple paths which lead to a transition:

 onTransition {
   case Active -&gt; _ =&gt; cancelTimer("activeTimer")
 }
 

Multiple such blocks are supported and all of them will be called, not only the first matching one.

Another feature is that other actors may subscribe for transition events by sending a SubscribeTransitionCallback message to this actor. Stopping a listener without unregistering will not remove the listener from the subscription list; use UnsubscribeTransitionCallback before stopping the listener.

State timeouts set an upper bound to the time which may pass before another message is received in the current state. If no external message is available, then upon expiry of the timeout a StateTimeout message is sent. Note that this message will only be received in the state for which the timeout was set and that any message received will cancel the timeout (possibly to be started again by the next transition).

Another feature is the ability to install and cancel single-shot as well as repeated timers which arrange for the sending of a user-specified message:

   setTimer("tock", TockMsg, 1 second, true) // repeating
   setTimer("lifetime", TerminateMsg, 1 hour, false) // single-shot
   cancelTimer("tock")
   isTimerActive("tock")
 


Nested Class Summary
static class FSM.$minus$greater$
          This extractor is just convenience for matching a (S, S) pair, including a reminder what the new state is.
static class FSM.CurrentState<S>
          Message type which is sent directly to the subscribed actor in FSM.SubscribeTransitionCallBack before sending any FSM.Transition messages.
static class FSM.CurrentState$
           
static class FSM.Event<D>
          All messages sent to the FSM will be wrapped inside an Event, which allows pattern matching to extract both state and data.
static class FSM.Event$
           
static class FSM.Failure
          Signifies that the FSM is shutting itself down because of an error, e.g.
static class FSM.Failure$
           
static class FSM.LogEntry<S,D>
          Log Entry of the LoggingFSM, can be obtained by calling getLog.
static class FSM.LogEntry$
           
static class FSM.Normal$
          Default reason if calling stop().
static class FSM.NullFunction$
          A partial function value which does not match anything and can be used to &ldquo;reset&rdquo; whenUnhandled and onTermination handlers.
static interface FSM.Reason
          Reason why this FSM is shutting down.
static class FSM.Shutdown$
          Reason given when someone was calling system.stop(fsm) from outside; also applies to Stop supervision directive.
static class FSM.State<S,D>
          This captures all of the managed state of the FSM: the state name, the state data, possibly custom timeout, stop reason and replies accumulated while processing the last message.
static class FSM.State$
           
static class FSM.StateTimeout$
          This case object is received in case of a state timeout.
static class FSM.StopEvent<S,D>
          Case class representing the state of the FSM whithin the onTermination block.
static class FSM.StopEvent$
           
static class FSM.SubscribeTransitionCallBack
          Send this to an FSM to request first the FSM.CurrentState and then a series of FSM.Transition updates.
static class FSM.SubscribeTransitionCallBack$
           
static class FSM.TimeoutMarker
          INTERNAL API
static class FSM.TimeoutMarker$
           
static class FSM.Timer
          INTERNAL API
static class FSM.Timer$
           
static class FSM.TransformHelper
           
static class FSM.Transition<S>
          Message type which is used to communicate transitions between states to all subscribed listeners (use FSM.SubscribeTransitionCallBack).
static class FSM.Transition$
           
static class FSM.UnsubscribeTransitionCallBack
          Unsubscribe from FSM.Transition notifications which was effected by sending the corresponding FSM.SubscribeTransitionCallBack.
static class FSM.UnsubscribeTransitionCallBack$
           
 
Nested classes/interfaces inherited from interface akka.actor.Actor
Actor.emptyBehavior$
 
Method Summary
 void applyState(FSM.State<S,D> nextState)
           
 void cancelTimer(java.lang.String name)
           
 FSM.State<S,D> currentState()
           
 boolean debugEvent()
           
 FSM.Event$ Event()
           
 long generation()
           
 scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> handleEvent()
           
 scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> handleEventDefault()
           
 void handleTransition(S prev, S next)
           
 void initialize()
           
 boolean isStateTimerActive()
           
 boolean isTimerActive(java.lang.String name)
           
 void logTermination(FSM.Reason reason)
          By default FSM.Failure is logged at error level and other reason types are not logged.
 void makeTransition(FSM.State<S,D> nextState)
           
 FSM.State<S,D> nextState()
           
 D nextStateData()
           
 void onTermination(scala.PartialFunction<FSM.StopEvent<S,D>,scala.runtime.BoxedUnit> terminationHandler)
           
 void onTransition(scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> transitionHandler)
           
 void postStop()
          User overridable callback.
 void processEvent(FSM.Event<D> event, java.lang.Object source)
           
 void processMsg(java.lang.Object value, java.lang.Object source)
           
 scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> receive()
          This defines the initial actor behavior, it must return a partial function with the actor logic.
 void register(S name, scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> function, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
           
 void setStateTimeout(S state, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
           
 void setTimer(java.lang.String name, java.lang.Object msg, scala.concurrent.duration.FiniteDuration timeout, boolean repeat)
           
 void startWith(S stateName, D stateData, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
          Set initial state.
 D stateData()
           
 scala.collection.mutable.Map<S,scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>>> stateFunctions()
           
 S stateName()
           
 FSM.StateTimeout$ StateTimeout()
          This case object is received in case of a state timeout.
 scala.collection.mutable.Map<S,scala.Option<scala.concurrent.duration.FiniteDuration>> stateTimeouts()
           
 FSM.State<S,D> stay()
          Produce "empty" transition descriptor.
 FSM.State<S,D> stop()
          Produce change descriptor to stop this FSM actor with reason "Normal".
 FSM.State<S,D> stop(FSM.Reason reason)
          Produce change descriptor to stop this FSM actor including specified reason.
 FSM.State<S,D> stop(FSM.Reason reason, D stateData)
          Produce change descriptor to stop this FSM actor including specified reason.
 FSM.StopEvent$ StopEvent()
           
 void terminate(FSM.State<S,D> nextState)
           
 scala.PartialFunction<FSM.StopEvent<S,D>,scala.runtime.BoxedUnit> terminateEvent()
           
 scala.Option<Cancellable> timeoutFuture()
           
 scala.collection.Iterator<java.lang.Object> timerGen()
           
 scala.collection.mutable.Map<java.lang.String,FSM.Timer> timers()
           
 scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> total2pf(scala.Function2<S,S,scala.runtime.BoxedUnit> transitionHandler)
           
 FSM.TransformHelper transform(scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> func)
           
 scala.collection.immutable.List<scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit>> transitionEvent()
           
 void when(S stateName, scala.concurrent.duration.FiniteDuration stateTimeout, scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> stateFunction)
          Insert a new StateFunction at the end of the processing chain for the given state.
 void whenUnhandled(scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> stateFunction)
           
 
Methods inherited from interface akka.actor.Actor
aroundPostRestart, aroundPostStop, aroundPreRestart, aroundPreStart, aroundReceive, context, postRestart, preRestart, preStart, self, sender, supervisorStrategy, unhandled
 
Methods inherited from interface akka.routing.Listeners
gossip, listenerManagement, listeners
 
Methods inherited from interface akka.actor.ActorLogging
_log, log
 

Method Detail

Event

FSM.Event$ Event()

StopEvent

FSM.StopEvent$ StopEvent()

StateTimeout

FSM.StateTimeout$ StateTimeout()
This case object is received in case of a state timeout.

Returns:
(undocumented)

when

void when(S stateName,
          scala.concurrent.duration.FiniteDuration stateTimeout,
          scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> stateFunction)
Insert a new StateFunction at the end of the processing chain for the given state. If the stateTimeout parameter is set, entering this state without a differing explicit timeout setting will trigger a StateTimeout event; the same is true when using #stay.

Parameters:
stateName - designator for the state
stateTimeout - default state timeout for this state
stateFunction - partial function describing response to input

startWith

void startWith(S stateName,
               D stateData,
               scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
Set initial state. Call this method from the constructor before the initialize() method. If different state is needed after a restart this method, followed by initialize(), can be used in the actor life cycle hooks Actor.preStart() and Actor.postRestart(java.lang.Throwable).

Parameters:
stateName - initial state designator
stateData - initial state data
timeout - state timeout for the initial state, overriding the default timeout for that state

stay

FSM.State<S,D> stay()
Produce "empty" transition descriptor. Return this from a state function when no state change is to be effected.

Returns:
descriptor for staying in current state

stop

FSM.State<S,D> stop()
Produce change descriptor to stop this FSM actor with reason "Normal".

Returns:
(undocumented)

stop

FSM.State<S,D> stop(FSM.Reason reason)
Produce change descriptor to stop this FSM actor including specified reason.

Parameters:
reason - (undocumented)
Returns:
(undocumented)

stop

FSM.State<S,D> stop(FSM.Reason reason,
                    D stateData)
Produce change descriptor to stop this FSM actor including specified reason.

Parameters:
reason - (undocumented)
stateData - (undocumented)
Returns:
(undocumented)

transform

FSM.TransformHelper transform(scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> func)

setTimer

void setTimer(java.lang.String name,
              java.lang.Object msg,
              scala.concurrent.duration.FiniteDuration timeout,
              boolean repeat)

cancelTimer

void cancelTimer(java.lang.String name)

isTimerActive

boolean isTimerActive(java.lang.String name)

setStateTimeout

void setStateTimeout(S state,
                     scala.Option<scala.concurrent.duration.FiniteDuration> timeout)

isStateTimerActive

boolean isStateTimerActive()

onTransition

void onTransition(scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> transitionHandler)

total2pf

scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> total2pf(scala.Function2<S,S,scala.runtime.BoxedUnit> transitionHandler)

onTermination

void onTermination(scala.PartialFunction<FSM.StopEvent<S,D>,scala.runtime.BoxedUnit> terminationHandler)

whenUnhandled

void whenUnhandled(scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> stateFunction)

initialize

void initialize()

stateName

S stateName()

stateData

D stateData()

nextStateData

D nextStateData()

debugEvent

boolean debugEvent()

currentState

FSM.State<S,D> currentState()

timeoutFuture

scala.Option<Cancellable> timeoutFuture()

nextState

FSM.State<S,D> nextState()

generation

long generation()

timers

scala.collection.mutable.Map<java.lang.String,FSM.Timer> timers()

timerGen

scala.collection.Iterator<java.lang.Object> timerGen()

stateFunctions

scala.collection.mutable.Map<S,scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>>> stateFunctions()

stateTimeouts

scala.collection.mutable.Map<S,scala.Option<scala.concurrent.duration.FiniteDuration>> stateTimeouts()

register

void register(S name,
              scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> function,
              scala.Option<scala.concurrent.duration.FiniteDuration> timeout)

handleEventDefault

scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> handleEventDefault()

handleEvent

scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> handleEvent()

terminateEvent

scala.PartialFunction<FSM.StopEvent<S,D>,scala.runtime.BoxedUnit> terminateEvent()

transitionEvent

scala.collection.immutable.List<scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit>> transitionEvent()

handleTransition

void handleTransition(S prev,
                      S next)

receive

scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> receive()
Description copied from interface: Actor
This defines the initial actor behavior, it must return a partial function with the actor logic.

Specified by:
receive in interface Actor
Returns:
(undocumented)

processMsg

void processMsg(java.lang.Object value,
                java.lang.Object source)

processEvent

void processEvent(FSM.Event<D> event,
                  java.lang.Object source)

applyState

void applyState(FSM.State<S,D> nextState)

makeTransition

void makeTransition(FSM.State<S,D> nextState)

postStop

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

terminate

void terminate(FSM.State<S,D> nextState)

logTermination

void logTermination(FSM.Reason reason)
By default FSM.Failure is logged at error level and other reason types are not logged. It is possible to override this behavior.

Parameters:
reason - (undocumented)