我需要启动Akka(2.0)演员系统,发送一些消息,然后等待它做重担。在那之后,我需要做一些与那些演员无关的事情。
我试图等待所有演员停止使用以下代码:
val system = new ActorSystem("parallelRunners")
val master = system.actorOf(Props[Master])
master ! Start
system.awaitTermination // <-- hangs here
所有演员都通过self ! PoisonPill
自杀。我做错了什么?
答案 0 :(得分:23)
在scka 2.11的Akka 2.4.1中,它似乎又有所不同。
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()
答案 1 :(得分:5)
我找到了解决方案 - 只需从主操作员调用system.shutdown:
context.system.shutdown
答案 2 :(得分:5)
对于那些遇到这个问题的人来说只是一个旁注:显然,Akka 2.5不再支持actorSystem.registerOnTermination(...)
了。原因之一可能是Akka避免任何阻塞呼叫的理念。相反,在ActorSystem
关闭时,Future
可用作执行操作的非阻塞方式。
尽管如此,您仍然可以通过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)
等待您的演员系统完成:
{{1}}
答案 3 :(得分:4)
您也可以使用ActorSystem
从主线程中删除system.shutdown
。但该操作是异步的。如果需要阻塞主线程直到完成,则只需使用system.awaitTermination
。如果你的parallelRunners返回对程序其余部分有用的东西,那么最好不要阻止并继续你的程序。
答案 4 :(得分:0)
在Akka 2.3.9中,似乎关闭一个actor系统并等待它关闭是一个两步的过程:
actorSystem.shutdown
actorSystem.awaitTermination
作为步骤(2)的替代方案,可能(尚未测试这些替代方案)您也可以在isTerminated
上轮询或使用registerOnTermination
在终止时运行某些代码。因此,值得仔细阅读akka.actor.ActorSystem的注释,以便在实现这些方法之间进行选择。
也许我错过了关于API(?)的其他选项,因为Future
返回值可能更好。
答案 5 :(得分:0)
怎么样:
import scala.concurrent.Await
import scala.concurrent.duration._
Await.ready(system.terminate(), 5.seconds)
terminate返回Future:
def terminate(): Future[Terminated]
你可以等待这个未来的完成。