[英]Capturing the message that killed an actor
当接收演员因该消息而死时,我正在尝试响应消息的发送者。 如果我在失败时Restart
演员,我会得到
preRestart(reason: Throwable, message: Option[Any])
但现在我承诺重新开始。
如果我Stop
演员,我只会得到
postStop()
什么不知道什么阻止了我自己。
与此同时,在主管中,我只得到了Throwable
并没有说明是什么导致了它。
我想,我可以通过DeadLetters
帖子演员终止,但这似乎是一个嘈杂的方法,因为我必须听所有死信和某处将终止与deadletter事件流相关联。
更新: DeadLetter
似乎不是一个选项。 导致死亡的消息甚至没有发送到DeadLetters,它只是消失了。
有没有我忽略的机制?
根据Akka用户列表中的这个帖子 ,在演员监督死亡周期中没有一个机制来实现这一点。 此外,文档明确声明消息已被删除:
如果在处理消息时抛出异常(即从其邮箱中取出并移交给当前行为),则此消息将丢失。 重要的是要了解它没有放回邮箱。 因此,如果要重试处理消息,则需要通过捕获异常并重试流程来自行处理。
理想的解决方案是使用专门的演员进行危险操作,并让发起人监视该演员的死亡以确定失败。
由于我的场景来自于被认为是安全的东西,但其中有一个错误,因此单独的actor选项可能是在事后 。 为了避免在try/catch
包装所有代码路径但能够保护更复杂和关键的流程,我最终创建了一个receive
包装器,让我拦截异常:
object SafeReceive {
def apply(receive: Receive)(recover: Any => PartialFunction[Throwable, Unit]): Receive =
new Receive {
override def isDefinedAt(x: Any): Boolean = receive.isDefinedAt(x)
override def apply(v1: Any): Unit = try {
receive(v1)
} catch recover(v1)
}
}
我可以用于这样的选择演员:
def receive = SafeReceive {
case ... => ...
} {
msg => {
case e: Exception =>
sender ! OperationFailed(msg, e)
throw e
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.