Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to postpone messages in Akka

Tags:

scala

akka

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?

like image 220
Scony Avatar asked Jan 17 '15 22:01

Scony


1 Answers

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.

like image 102
Ryan Avatar answered Sep 20 '22 17:09

Ryan