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 and stash() your phaseB messages for later.
When your FSM is in phaseA and receives a phaseB message, call stash(). When that actor then transitions into the phaseB state, call unstashAll() and all the stashed messages will be redelivered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With