Entry actions with Akka FSM

451 views Asked by At

Any state machine of reasonable complexity requires some entry actions to be performed upon entry to a state. For instance, UML State Machine diagrams have a special action for this purpose. Unfortunately I don't see how I can model such entry actions (or exit actions) in Akka FSM. Performing the actions on transitions (using underscore outgoing state) doesn't work since entry actions are intended to change the state data (e.g. preparing data structures required for operation in the new state). Any advice on how to model entry/exit actions in Akka FSM?

4

There are 4 answers

0
user3927784 On

I had the same problem and I played a while modifying the original FSM trait to deal with entry/exit.

https://github.com/jock71/jock-akka-fsm/blob/master/src/main/scala/jok/akka/fsm/FsmMod.scala

An usage example can be found at:

https://github.com/jock71/jock-akka-fsm/blob/master/src/main/scala/jok/akka/fsm/TestAkkaFsm.scala

Not very clear to me how to deal with StateData when is specified both in goto using and changed in entry handler

0
jake256 On

As noted in Akka's FSM documentation, An initial currentState -> currentState notification will be triggered [after calling initialize].

Something like this should work:

onTransition {
  case InitialState -> InitialState =>
    // Do stuff
}
2
Josep Prat On

If you want to add entry or exit actions for a state you need to use write some PartialFunction on the onTransition.
For example, this is how you model entry or exit actions in AkkaFSM:

onTransition {
   case _ -> StateA => /* This is an entry action for StateA. Do something here. You can send messages to actors (or self), so some state checks or setups. */
   case StateA -> _ => /* This is an exit action for StateA. Do something here. You can send messages to actors (or self), so some state post-checks or any cleanup task for the state */
}
0
Synox On

The book Akka in Action also uses the entry actions from UML. They implement entry actions using transitions with wildcards and use external events to change the state (but not the state data).

There is a complete scala example on github. The relevant part in scala:

onTransition {
    case _ -> WaitForRequests => {
      if (!nextStateData.pendingRequests.isEmpty) {
        // go to next state
        self ! PendingRequests
      }
    }

Or translated into java:

onTransition(
  matchState(null, WaitForRequests.class, () -> {
    if (!nextStateData().pendingRequests.isEmpty()) {
        // go to next state
        self().tell(PendingRequests, self());
        }
    }
  })