Correct way to postpone messages in Akka

2019-04-29 05:20发布

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?

标签: scala akka
1条回答
ゆ 、 Hurt°
2楼-- · 2019-04-29 05:25

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.

查看更多
登录 后发表回答