2017-02-20 1 views
0

Ich bin ein Schauspieler mit mehreren Zuständen implementieren und Stash verwenden, um keine Nachrichten zu verlieren. Meine Zustände initialisieren (etwas von der DB holen), laufen (Anfragen bearbeiten) und aktualisieren (meinen Zustand aktualisieren). Mein Problem ist, dass ich die Nachrichten verliere, wenn ich versuche unstashAll() in Zukunft zu lösen.akka unstashAlle funktioniert nicht

def initializing: Receive = { 
case Initialize => 
    log.info("initializing") 
    (for { 
    items1 <- db.getItems("1") 
    items2 <- db.getItems("2") 
    } yield items1 ::: items2) map {items => 
    unstashAll() 
    context.become(running(items)) 
    } 
case r => 
    log.debug(s"actor received message: $r while initializing and stashed it for further processing") 
    stash()} 

ich es feste meine Implementierung durch die Umstellung auf diese

def initializing: Receive = { 
case Initialize => 
    log.info("initializing") 
    (for { 
    items1 <- db.getItems("1") 
    items2 <- db.getItems("2") 
    } yield items1 ::: items2) pipeTo self 
    context.become({ 
    case items: List[Item] => 
     unstashAll() 
     context.become(running(items)) 
    case r => 
     log.debug(s"actor received message: $r while initializing and stashed it for further processing") 
     stash() 
    }) 
case r => 
    log.debug(s"actor received message: $r while initializing and stashed it for further processing") 
    stash()} 

kann mir jemand erklären, warum die erste Arbeit nicht?

Antwort

1

Ich denke, der unstashAll Teil funktioniert gut. Das Problem ist, dass Sie es zusammen mit Ihrem context.become als Teil eines zukünftigen Rückrufs ausgeführt haben.

Dies bedeutet, dass der Code in Ihrem map Block die Vorhersagbarkeit Ihrer akteurssequentiellen Verarbeitung vermeidet. Mit anderen Worten, könnte dies geschehen:

  1. rufen Sie unstashAll
  2. Ihre Nachrichten werden in den Schauspielern Briefkasten zurück
  3. der Schauspieler nimmt Ihre Nachrichten nacheinander. Der Kontext hat sich noch nicht geändert, so dass sie wieder verstaute
  4. Ihrem Kontext wird schließlich running (aber es ist zu spät)

Die Lösung ist - wie Sie herausgefunden - das pipeTo Muster, das im Wesentlichen ein sendet Future s Ergebnis für den Schauspieler als Nachricht. Dies macht alles sequenziell und vorhersehbar.

Verwandte Themen