I'm using akka cluster in order to perform distributed computations in two pahses. First phaseA
then phaseB
. To handle phases I use akka's FSM.
There is no hard synchronization so one of the nodes may reach phaseB
while others are still in phaseA
.
The problem is, one in phaseB
sends phaseB-related
messages to others (they are in phaseA
yet) what causes them to loose phaseB-related
messages.
For now I use simple trick to postpone unknown messages:
case any => self ! any
But IMO this is not proper way to do that. I know I can also schedule any
using akka scheduler, but I don't like this either.
Here is simplified code:
package whatever
import akka.actor._
object Test extends App {
case object PhaseA
case object PhaseB
class Any extends Actor {
def phaseA: Receive = {
case PhaseA => {
context.become(phaseB)
println("in phaseB now")
}
case any => self ! any
}
def phaseB: Receive = {
case PhaseB => println("got phaseB message !")
}
def receive = phaseA
}
val system = ActorSystem("MySystem")
val any = system.actorOf(Props(new Any), name = "any")
any ! PhaseB
any ! PhaseA
}
What is the correct way to postpone messages in such a situation?
You can stash messages for later processing. Mix
akka.actor.Stash
into your actors andstash()
yourphaseB
messages for later.When your FSM is in
phaseA
and receives aphaseB
message, callstash()
. When that actor then transitions into thephaseB
state, callunstashAll()
and all the stashed messages will be redelivered.