2012-09-15 50 views
9

我需要啓動Akka(2.0)actor系統,發送一些消息,然後等待它完成繁重的工作。之後,我需要做一些與演員無關的事情。如何等待Akka演員系統終止?

我試圖等待所有參與者停止與下面的代碼:

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

所有參與者通過self ! PoisonPill自殺。我究竟做錯了什麼?

回答

4

我找到了解決辦法 - 只要撥打system.shutdown從主演員:

context.system.shutdown 
+9

請注意:[截至Akka 2.4](http://doc.akka.io/docs/akka/snapshot/project/migration-guide-2.3.x-2.4.x.html#Actor_system_shutdown),你應該使用'ActorSystem.terminate()'而不是'ActorSystem.shutdown()' – 203

4

您還可以通過使用system.shutdown殺死在主線程的ActorSystem。但該操作是異步的。如果您需要阻止主線程直到完成,則只需使用system.awaitTermination。如果您的parallelRunner返回對程序其餘部分有用的內容,那麼最好不要阻止並繼續您的程序。

6

從Akka 2.4開始,您應該使用system.awaitTermination(),它返回Future[Terminated]您可以等待。

爲了終止系統,你應該使用ActorSystem.terminate(如context.system.terminate()從當它完成了一個演員中

來源:Release Notes

16

在阿卡2.4.1斯卡拉2.11這似乎是又不同。

system.awaitTermination()已被棄用,該文檔指導我們使用Await.result(system.whenTerminated, timeout)來代替。

由於203表示,system.terminate仍然是終止系統的方式。

下面是一些示例代碼,我用:

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)) 
在MyActor類我行

然後context.system.terminate()

0
在阿卡2.3.9

,似乎關停演員操作系統和等待它關閉是兩個步驟:

  1. 啓動關機: actorSystem.shutdown
  2. 等待其處於阻斷的方式終止: actorSystem.awaitTermination

作爲替代在步驟(2),可能(沒有測試這些替代),則可能替換地輪詢isTerminated或使用registerOnTermination用於運行一些代碼時,它的終止。因此,值得通過akka.actor.ActorSystem的評論來深入瞭解並選擇這些方法來實現。

也許我錯過了關於API(?)的其他選項,因爲Future返回值本可以更好。

3

只是一個旁註爲那些遇到這個問題的標題:顯然,阿卡2。5不再支持actorSystem.awaitTermination。原因是爲什麼可能是Akka的避免任何阻塞呼叫的理念。相反,actorSystem.registerOnTermination(...)可以用作非阻塞方式來執行操作,而ActorSystem正在關閉。

儘管如此,你仍然可以等待你的演員系統通過由ActorSystem.whenTerminated提供Future完成:

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

如何:

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

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

終止回報的未來:

def terminate(): Future[Terminated] 

,你可以等待這個未來的完成。