【发布时间】:2011-09-04 10:36:06
【问题描述】:
我目前正在尝试开始使用 Akka,但遇到了一个奇怪的问题。我的 Actor 有以下代码:
class AkkaWorkerFT extends Actor {
def receive = {
case Work(n, c) if n < 0 => throw new Exception("Negative number")
case Work(n, c) => self reply n.isProbablePrime(c);
}
}
这就是我开始工作的方式:
val workers = Vector.fill(nrOfWorkers)(actorOf[AkkaWorkerFT].start());
val router = Routing.loadBalancerActor(SmallestMailboxFirstIterator(workers)).start()
这就是我关闭一切的方式:
futures.foreach( _.await )
router ! Broadcast(PoisonPill)
router ! PoisonPill
现在发生的情况是,如果我向工作人员发送 n > 0 的消息(不抛出异常),一切正常并且应用程序正常关闭。但是,只要我向它发送一条导致异常的消息,应用程序就不会终止,因为仍然有一个演员在运行,但我不知道它来自哪里。
如果有帮助,这是相关线程的堆栈:
Thread [akka:event-driven:dispatcher:event:handler-6] (Suspended)
Unsafe.park(boolean, long) line: not available [native method]
LockSupport.park(Object) line: 158
AbstractQueuedSynchronizer$ConditionObject.await() line: 1987
LinkedBlockingQueue<E>.take() line: 399
ThreadPoolExecutor.getTask() line: 947
ThreadPoolExecutor$Worker.run() line: 907
MonitorableThread(Thread).run() line: 680
MonitorableThread.run() line: 182
PS:没有终止的线程不是任何工作线程,因为我添加了一个 postStop 回调,它们每个都正常停止。
PPS:Actors.registry.shutdownAll 解决了这个问题,但我认为 shutdownAll 只能作为最后的手段,不是吗?
【问题讨论】:
-
@ViktorKlang:但是为什么它仍然存在,我该如何正确地停止它? :)
-
什么时候应该停止?关闭方法见这里:akka.io/api/akka/1.1.2/#akka.event.EventHandler$
-
当您使用 Akka 的“日志记录”的默认事件处理程序时启动它。它可以在 akka.conf 中配置
-
@Pablo Fernandez:但是为什么我必须禁用日志记录才能让我的应用程序正确终止?恕我直言,这更像是一种解决方法而不是解决方案......
-
@x3ro:偶然发现了这个(在寻找不终止的原因时)。已经能够验证剩下的演员确实是
EventHandler? (对我来说是。)听起来很有趣,所以我检查了代码:对你来说,原因似乎是抛出异常会导致EventHandler.error被调用(打印堆栈跟踪?)....我猜你还必须在 EventHandler 上扔一个 PoisonPill 来关闭它,一些 akka 专家可能有更好(更好)的解决方案。
标签: scala routing actor akka fault-tolerance