2012-09-15 21 views
9

Necesito iniciar el sistema actor Akka (2.0), enviar algunos mensajes y esperar a que haga un trabajo pesado. Después de eso, necesito hacer algo que no esté relacionado con esos actores.¿Cómo se espera que termine el sistema Akka actor?

traté de esperar que todos los actores se detienen con siguiente código:

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

Todos los actores se suicidan a través self ! PoisonPill. ¿Qué estoy haciendo mal?

Respuesta

4

he encontrado la solución - simplemente llame system.shutdown del actor principal:

context.system.shutdown 
+9

Tenga en cuenta: [a partir de Akka 2.4] (http://doc.akka.io/docs/akka/snapshot/project/migration-guide-2.3.x-2.4.x.html#Actor_system_shutdown), debería use 'ActorSystem.terminate()' en lugar de 'ActorSystem.shutdown()' – 203

4

También puede matar al ActorSystem desde el hilo principal mediante el uso de system.shutdown. Pero esa operación es asincrónica. Solo necesita usar system.awaitTermination si necesita bloquear el hilo principal hasta que finalice. Si tus parallelRunners devuelven algo útil para el resto del programa, probablemente sería más fácil no bloquear y continuar tu programa.

6

A partir de Akka 2.4, debe usar system.awaitTermination() que devuelve Future[Terminated] que puede esperar.

Con el fin de interrumpir el sistema, se debe utilizar ActorSystem.terminate (por ejemplo context.system.terminate() desde el interior de un actor cuando esté terminado

Fuente:. Release Notes

16

En Akka 2.4.1 para Scala 2.11 parece ser diferente otra vez.

system.awaitTermination() es obsoleto y los documentos nos instruyen a utilizar Await.result(system.whenTerminated, timeout) lugar.

Como 203 dijo, system.terminate sigue siendo la manera de terminar el sistema.

Aquí es un código de ejemplo he utilizado:

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)) 

Luego, en la clase MyActor Tengo la línea context.system.terminate()

0

en Akka 2.3.9, parece que el cierre de un sistema de actor y en espera de que se apague es un proceso de dos pasos:

  1. iniciar el apagado: actorSystem.shutdown
  2. Esperar su terminación en forma de bloqueo: actorSystem.awaitTermination

Como alternativa a la etapa (2), posiblemente (no han probado estas alternativas) se puede sondear alternativamente sobre isTerminated o utilizar registerOnTermination para ejecutar código cuando se termina. Por lo tanto, vale la pena examinar los comentarios de akka.actor.ActorSystem para profundizar y elegir entre estos métodos para su implementación.

Quizás me faltan otras opciones sobre la API (?) Como Future los valores de devolución podrían haber sido mejores.

3

Sólo una nota al margen para los que se encuentran con esta pregunta por su título: Al parecer, Akka 2.5 ya no es compatible con actorSystem.awaitTermination. La razón por la cual podría ser la filosofía de Akka de evitar cualquier llamada de bloqueo. En cambio, actorSystem.registerOnTermination(...) se puede utilizar como una forma no bloqueante para realizar acciones mientras se está cerrando un ActorSystem.

No obstante, todavía se puede esperar a que su sistema de actor para completar a través de un Future proporcionada por ActorSystem.whenTerminated:

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

¿Qué tal:

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

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

terminar vuelve un futuro:

def terminate(): Future[Terminated] 

y puede esperar la finalización de este futuro.

Cuestiones relacionadas