2012-09-15 7 views
9

Ich brauche Akka (2.0) Aktorik, sendet in einigen Nachrichten zu starten, dann warten Sie, schweres Heben zu tun. Danach muss ich etwas unternehmen, das nichts mit diesen Schauspielern zu tun hat.Wie man wartet, bis Akka actor System beendet wird?

Ich habe versucht, für alle Akteure zu warten, mit folgendem Code zu stoppen:

val system = new ActorSystem("parallelRunners") 
val master = system.actorOf(Props[Master]) 
master ! Start 
system.awaitTermination // <-- hangs here 

Alle Akteure bringen sich über self ! PoisonPill. Was mache ich falsch?

Antwort

4

fand ich die Lösung - nur system.shutdown vom Master Schauspieler nennen:

context.system.shutdown 
+9

Bitte beachten Sie: [ab Akka 2.4] (http://doc.akka.io/docs/akka/snapshot/project/migration-guide-2.3.x-2.4.x.html#Actor_system_shutdown) sollten Sie Verwenden Sie 'ActorSystem.terminate()' anstelle von 'ActorSystem.shutdown()' – 203

4

Sie können auch unter Verwendung von system.shutdown die ActorSystem aus dem Haupt-Thread töten. Aber diese Operation ist asynchron. Sie müssen nur system.awaitTermination verwenden, wenn Sie den Haupt-Thread bis zum Abschluss blockieren müssen. Wenn Ihre ParallelRunner etwas Nützliches für den Rest des Programms zurückgeben, wäre es wahrscheinlich am einfachsten, Ihr Programm nicht zu blockieren und fortzusetzen.

6

Ab Akka 2.4, sollten Sie system.awaitTermination() verwenden, die eine Future[Terminated] kehrt sie warten.

Um das System zu beenden, sollten Sie verwenden ActorSystem.terminate (zB context.system.terminate() aus einem Schauspieler, wenn es fertig ist

. Quelle: Release Notes

16

In Akka 2.4.1 für scala 2.11 scheint es zu sein, wieder anders.

system.awaitTermination() ist veraltet und die docs anweisen uns Await.result(system.whenTerminated, timeout) stattdessen zu verwenden.

Als 203 sagte, system.terminate ist immer noch der Weg, um das System zu beenden.

Hier einige Beispiel-Code ist ich verwendet:

val actorSystem = ActorSystem("ActorSystem") 
val myActors = actorSystem.actorOf(Props[MyActor].withRouter(RoundRobinPool(10)), "MyActors") 
rainbows.foreach(rainbow => myActors ! rainbow) 
Await.ready(actorSystem.whenTerminated, Duration(1, TimeUnit.MINUTES)) 

Dann in der MyActor Klasse I die Linie context.system.terminate() haben

0

in Akka 2.3.9 scheint es, dass ein Schauspieler System heruntergefahren und wartet auf es herunterzufahren ist ein zweistufiger Prozess:

  1. einleiten Abschaltung: actorSystem.shutdown
  2. Warten seine Kündigung in einer blockierenden Weise: actorSystem.awaitTermination

Als Alternative (2) zu dem Schritt, möglicherweise (habe diese Alternativen nicht getestet) Sie auf isTerminated alternativ abfragen können oder registerOnTermination für den Betrieb einen Code verwenden, wenn es beendet wird. Es lohnt sich also, die Kommentare von akka.actor.ActorSystem durchzugehen und zwischen diesen Methoden für Ihre Implementierung zu wählen.

Vielleicht andere Optionen über die API fehlt mir (?) Als Future Rückgabewerte könnte schöner sein können.

3

nur eine Randnotiz für die in dieser Frage für den Titel läuft: Offenbar Akka 2.5 unterstützt actorSystem.awaitTermination nicht mehr. Grund dafür könnte Akkas Philosophie sein, blockierende Anrufe zu vermeiden. Stattdessen kann actorSystem.registerOnTermination(...) als nicht blockierende Möglichkeit verwendet werden, Aktionen auszuführen, während ActorSystem heruntergefahren wird.

Trotzdem können Sie noch für Ihren Schauspieler System warten über eine Future von ActorSystem.whenTerminated vorgesehen abzuschließen:

val system = new ActorSystem("parallelRunners") 
val master = system.actorOf(Props[Master]) 
master ! Start 

import scala.concurrent.Await 
import scala.concurrent.duration._ 
Await.ready(system.whenTerminated, 365.days) 
0

Wie wäre:

import scala.concurrent.Await 
import scala.concurrent.duration._ 

Await.ready(system.terminate(), 5.seconds) 

beenden kehrt eine Zukunft:

def terminate(): Future[Terminated] 

und Sie können nur auf die Fertigstellung dieser Zukunft warten.

Verwandte Themen