akka.actor
Interface FSM<S,D>

All Superinterfaces:
Actor, ActorLogging, Listeners
All Known Subinterfaces:
LoggingFSM<S,D>
All Known Implementing Classes:
ClusterSingletonManager, ReliableProxy, 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 -> _ => 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; use UnsubscribeTransitionCallback before stopping the other actor.

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
          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 “reset” 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
          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$
           
private static class FSM.TimeoutMarker
          INTERNAL API
private static class FSM.TimeoutMarker$
           
private static class FSM.Timer
          INTERNAL API
private 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)
          Cancel named timer, ensuring that the message is not subsequently delivered (no race).
 FSM.State<S,D> currentState()
           
 boolean debugEvent()
           
 long generation()
           
 scala.PartialFunction<FSM.Event,FSM.State<S,D>> handleEvent()
           
 scala.PartialFunction<FSM.Event,FSM.State<S,D>> handleEventDefault()
           
 void handleTransition(S prev, S next)
           
 void initialize()
          Verify existence of initial state and setup timers.
 boolean isStateTimerActive()
          INTERNAL API, used for testing.
 boolean isTimerActive(java.lang.String name)
          Inquire whether the named timer is still active.
 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()
          Return next state data (available in onTransition handlers)
 void onTermination(scala.PartialFunction<FSM.StopEvent,scala.runtime.BoxedUnit> terminationHandler)
          Set handler which is called upon termination of this FSM actor.
 void onTransition(scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> transitionHandler)
          Set handler which is called upon each state transition, i.e.
 void postStop()
          Call onTermination hook; if you want to retain this behavior when overriding make sure to call super.postStop().
 void processEvent(FSM.Event 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,FSM.State<S,D>> function, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
           
 void setStateTimeout(S state, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
          Set state timeout explicitly.
 void setTimer(java.lang.String name, java.lang.Object msg, scala.concurrent.duration.FiniteDuration timeout, boolean repeat)
          Schedule named timer to deliver message after given delay, possibly repeating.
 void startWith(S stateName, D stateData, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
          Set initial state.
 D stateData()
          Return current state data (i.e.
 scala.collection.mutable.Map<S,scala.PartialFunction<FSM.Event,FSM.State<S,D>>> stateFunctions()
           
 S stateName()
          Return current state name (i.e.
 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.
 void terminate(FSM.State<S,D> nextState)
           
 scala.PartialFunction<FSM.StopEvent,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)
          Convenience wrapper for using a total function instead of a partial function literal.
 FSM.TransformHelper transform(scala.PartialFunction<FSM.Event,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,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,FSM.State<S,D>> stateFunction)
          Set handler which is called upon reception of unhandled messages.
 
Methods inherited from interface akka.actor.Actor
context, noSender, 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
 

Method Detail

StateTimeout

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


when

void when(S stateName,
          scala.concurrent.duration.FiniteDuration stateTimeout,
          scala.PartialFunction<FSM.Event,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".


stop

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


stop

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


transform

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

setTimer

void setTimer(java.lang.String name,
              java.lang.Object msg,
              scala.concurrent.duration.FiniteDuration timeout,
              boolean repeat)
Schedule named timer to deliver message after given delay, possibly repeating.

Parameters:
name - identifier to be used with cancelTimer()
msg - message to be delivered
timeout - delay of first message delivery and between subsequent messages
repeat - send once if false, scheduleAtFixedRate if true

cancelTimer

void cancelTimer(java.lang.String name)
Cancel named timer, ensuring that the message is not subsequently delivered (no race).

Parameters:
name - of the timer to cancel

isTimerActive

boolean isTimerActive(java.lang.String name)
Inquire whether the named timer is still active. Returns true unless the timer does not exist, has previously been canceled or if it was a single-shot timer whose message was already received.


setStateTimeout

void setStateTimeout(S state,
                     scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
Set state timeout explicitly. This method can safely be used from within a state handler.


isStateTimerActive

boolean isStateTimerActive()
INTERNAL API, used for testing.


onTransition

void onTransition(scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> transitionHandler)
Set handler which is called upon each state transition, i.e. not when staying in the same state. This may use the pair extractor defined in the FSM companion object like so:

 onTransition {
   case Old -> New => doSomething
 }
 

It is also possible to supply a 2-ary function object:

 onTransition(handler _)

 private def handler(from: S, to: S) { ... }
 

The underscore is unfortunately necessary to enable the nicer syntax shown above (it uses the implicit conversion total2pf under the hood).

Multiple handlers may be installed, and every one of them will be called, not only the first one matching.


total2pf

scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> total2pf(scala.Function2<S,S,scala.runtime.BoxedUnit> transitionHandler)
Convenience wrapper for using a total function instead of a partial function literal. To be used with onTransition.


onTermination

void onTermination(scala.PartialFunction<FSM.StopEvent,scala.runtime.BoxedUnit> terminationHandler)
Set handler which is called upon termination of this FSM actor. Calling this method again will overwrite the previous contents.


whenUnhandled

void whenUnhandled(scala.PartialFunction<FSM.Event,FSM.State<S,D>> stateFunction)
Set handler which is called upon reception of unhandled messages. Calling this method again will overwrite the previous contents.

The current state may be queried using stateName.


initialize

void initialize()
Verify existence of initial state and setup timers. This should be the last call within the constructor, or Actor.preStart() and Actor.postRestart(java.lang.Throwable)

See Also:
startWith(S, D, scala.Option)

stateName

S stateName()
Return current state name (i.e. object of type S)


stateData

D stateData()
Return current state data (i.e. object of type D)


nextStateData

D nextStateData()
Return next state data (available in onTransition handlers)


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,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,FSM.State<S,D>> function,
              scala.Option<scala.concurrent.duration.FiniteDuration> timeout)

handleEventDefault

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

handleEvent

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

terminateEvent

scala.PartialFunction<FSM.StopEvent,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

processMsg

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

processEvent

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

applyState

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

makeTransition

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

postStop

void postStop()
Call onTermination hook; if you want to retain this behavior when overriding make sure to call super.postStop().

Please note that this method is called by default from preRestart(), so override that one if onTermination shall not be called during restart.

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.