我有一个akka系统,它基本上是两个 生产环境 者演员,它们向一个消费者演员发送消息 . 在简化的形式我有这样的事情:
class ProducerA extends Actor {
def receive = {
case Produce => Consumer ! generateMessageA()
}
... more code ...
}
class ProducerB extends Actor {
def receive = {
case Produce => Consumer ! generateMessageB()
}
... more code ...
}
class Consumer extends Actor {
def receive = {
case A => handleMessageA(A)
case B => handleMessageB(B)
}
... more code ...
}
他们都是同一个akka系统的兄弟姐妹 .
我试图弄清楚如何优雅地终止这个系统 . 这意味着在关机时我希望 ProducerA
和 ProducerB
立即停止然后我希望 Consumer
完成处理消息队列中剩余的任何消息然后关闭 .
看起来我想要的是 Consumer
演员能够观察 ProducerA
和 ProducerB
的终止 . 或者通常,似乎我想要的是能够在两个 生产环境 者停止后向 Consumer
发送 PoisonPill
消息 .
https://alvinalexander.com/scala/how-to-monitor-akka-actor-death-with-watch-method
上面的教程很好地解释了一个演员如何观看另一个演员的终止,但不确定演员如何观察多个演员的终止 .
3 回答
它可以使用 ProducerWatchers actor实现,它管理 生产环境 者被杀死,一旦所有生成器被杀死,你可以杀死Consumer actor,然后是ProducerWatchers actor .
一个演员可以通过
context.watch
的多次调用来观看多个演员,每次调用都会传入不同的ActorRef
. 例如,您的Consumer
actor可以通过以下方式观看Producer
演员的终止:两个
Producer
演员都会发送他们各自对Consumer
的引用,然后监视Producer
演员终止 . 当Producer
actor都被终止时,Consumer
会向自己发送一个PoisonPill
. 因为PoisonPill is treated like a normal message in an actor's mailbox,Consumer
将在处理PoisonPill
并关闭自身之前处理已排队的所有消息 .类似的模式在Derek Wyatt's "Shutdown Patterns in Akka 2" blog post中描述,在Akka文档中提到 .
所以我最终选择的解决方案受到Derek Wyatt's terminator pattern的启发
这或多或少正是我想要的 . 根据期货的履行情况,消费者关闭等待 生产环境 者关闭 . 此外,整个关闭本身会导致未来,您可以等待,因此能够保持线程足够长,以便正确清理所有内容 .