|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface FSM<S,D>
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.
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 “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<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 |
---|
FSM.Event$ Event()
FSM.StopEvent$ StopEvent()
FSM.StateTimeout$ StateTimeout()
void when(S stateName, scala.concurrent.duration.FiniteDuration stateTimeout, scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> stateFunction)
stateName
- designator for the statestateTimeout
- default state timeout for this statestateFunction
- partial function describing response to inputvoid startWith(S stateName, D stateData, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
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)
.
stateName
- initial state designatorstateData
- initial state datatimeout
- state timeout for the initial state, overriding the default timeout for that stateFSM.State<S,D> stay()
FSM.State<S,D> stop()
FSM.State<S,D> stop(FSM.Reason reason)
reason
- (undocumented)
FSM.State<S,D> stop(FSM.Reason reason, D stateData)
reason
- (undocumented)stateData
- (undocumented)
FSM.TransformHelper transform(scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> func)
void setTimer(java.lang.String name, java.lang.Object msg, scala.concurrent.duration.FiniteDuration timeout, boolean repeat)
void cancelTimer(java.lang.String name)
boolean isTimerActive(java.lang.String name)
void setStateTimeout(S state, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
boolean isStateTimerActive()
void onTransition(scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> transitionHandler)
scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit> total2pf(scala.Function2<S,S,scala.runtime.BoxedUnit> transitionHandler)
void onTermination(scala.PartialFunction<FSM.StopEvent<S,D>,scala.runtime.BoxedUnit> terminationHandler)
void whenUnhandled(scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> stateFunction)
void initialize()
S stateName()
D stateData()
D nextStateData()
boolean debugEvent()
FSM.State<S,D> currentState()
scala.Option<Cancellable> timeoutFuture()
FSM.State<S,D> nextState()
long generation()
scala.collection.mutable.Map<java.lang.String,FSM.Timer> timers()
scala.collection.Iterator<java.lang.Object> timerGen()
scala.collection.mutable.Map<S,scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>>> stateFunctions()
scala.collection.mutable.Map<S,scala.Option<scala.concurrent.duration.FiniteDuration>> stateTimeouts()
void register(S name, scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> function, scala.Option<scala.concurrent.duration.FiniteDuration> timeout)
scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> handleEventDefault()
scala.PartialFunction<FSM.Event<D>,FSM.State<S,D>> handleEvent()
scala.PartialFunction<FSM.StopEvent<S,D>,scala.runtime.BoxedUnit> terminateEvent()
scala.collection.immutable.List<scala.PartialFunction<scala.Tuple2<S,S>,scala.runtime.BoxedUnit>> transitionEvent()
void handleTransition(S prev, S next)
scala.PartialFunction<java.lang.Object,scala.runtime.BoxedUnit> receive()
Actor
receive
in interface Actor
void processMsg(java.lang.Object value, java.lang.Object source)
void processEvent(FSM.Event<D> event, java.lang.Object source)
void applyState(FSM.State<S,D> nextState)
void makeTransition(FSM.State<S,D> nextState)
void postStop()
Actor
postStop
in interface Actor
void terminate(FSM.State<S,D> nextState)
void logTermination(FSM.Reason reason)
FSM.Failure
is logged at error level and other reason
types are not logged. It is possible to override this behavior.
reason
- (undocumented)
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |