2015-01-17 2 views
6

Sto usando il cluster akka per eseguire calcoli distribuiti in due pahses. Prima phaseA quindi phaseB. Per gestire le fasi uso l'FSM di akka.Modo corretto per posticipare i messaggi in Akka

Non è presente alcuna sincronizzazione hardware, pertanto uno dei nodi può raggiungere phaseB mentre altri sono ancora nello phaseA.

Il problema è, uno in phaseB invia phaseB-related messaggi ad altri (che sono in phaseA ancora) che cosa li fa perdere phaseB-related messaggi.

Per ora io uso semplice trucco di rinviare i messaggi sconosciuti:

case any => self ! any 

Ma IMO questo non è modo corretto di farlo. So che posso anche programmare any usando lo schedulatore akka, ma non mi piace neanche questo.

Qui è semplificato codice:

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 
} 

Qual è il modo corretto di rinviare i messaggi in una situazione del genere?

+0

Chiedere all'attore nella fase A di mettere i messaggi in coda e poi inviarli a se stesso quando entra nella fase B. Ragioni degli attori come se fossero persone. Cosa faresti se qualcuno ti consegnasse un messaggio su un pezzo di carta che non sei ancora pronto a gestire? Metti la pila sulla scrivania finché non sei pronto per occupartene. –

risposta

12

È possibile memorizzare i messaggi per l'elaborazione successiva. Mescola akka.actor.Stash nei tuoi attori e stash() i tuoi messaggi phaseB per dopo.

Quando il vostro FSM è in phaseA e riceve un messaggio phaseB, chiamare stash(). Quando quell'attore passa quindi allo stato phaseB, chiama unstashAll() e tutti i messaggi nascosti saranno riconsegnati.