19

我需要启动 Akka (2.0) 演员系统,发送一些消息,然后等待它完成繁重的工作。在那之后,我需要做一些与那些演员无关的事情。

我试图等待所有演员停止使用以下代码:

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

所有演员都通过self ! PoisonPill. 我究竟做错了什么?

4

7 回答 7

28

在 scala 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()

于 2016-02-02T18:40:13.187 回答
7

从 Akka 2.4 开始,您应该使用system.awaitTermination()which 返回一个Future[Terminated]您可以等待的。

为了终止系统,你应该使用ActorSystem.terminate(例如context.system.terminate(),当它完成时从一个actor内部。

来源:发行说明

于 2015-11-23T17:11:58.030 回答
6

对于那些遇到这个问题的人来说只是一个旁注:显然,Akka 2.5 不再支持actorSystem.awaitTermination了。原因可能是 Akka 避免任何阻塞调用的哲学。相反,可以用作在关闭actorSystem.registerOnTermination(...)时执行操作的非阻塞方式。ActorSystem

Future尽管如此,您仍然可以通过提供的 by等待您的演员系统完成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)
于 2017-06-16T14:00:31.340 回答
4

我找到了解决方案 - 只需从主演员那里调用 system.shutdown :

context.system.shutdown
于 2012-09-15T10:36:42.853 回答
4

您还可以ActorSystem使用system.shutdown. 但是该操作是异步的。system.awaitTermination仅当您需要阻塞主线程直到它完成时才需要使用。如果您的 parallelRunners 返回对程序的其余部分有用的东西,那么不阻塞并继续您的程序可能是最简单的。

于 2013-11-22T15:56:26.863 回答
0

在 Akka 2.3.9 中,关闭 Actor 系统并等待它关闭似乎是一个两步过程:

  1. 启动关机: actorSystem.shutdown
  2. 以阻塞方式等待其终止: actorSystem.awaitTermination

作为步骤 (2) 的替代方法,可能(尚未测试这些替代方法)您可以选择轮询isTerminatedregisterOnTermination用于在终止时运行某些代码。因此,值得通过 akka.actor.ActorSystem 的注释来了解并在这些方法之间为您的实现进行选择。

也许我错过了有关 API 的其他选项(?),因为Future返回值可能会更好。

于 2016-08-13T11:23:23.323 回答
0

怎么样:

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

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

终止返回一个未来:

def terminate(): Future[Terminated]

你可以等待这个未来的完成。

于 2017-06-29T14:08:26.273 回答