当接收者因该消息而死亡时,我试图回复消息的发送方。如果我Restart的演员失败,我会得到
preRestart(reason: Throwable, message: Option[Any])但现在我决心重新开始。
如果我Stop演员,我只会得到
postStop()不知道是什么阻止了我自己。
同时,在主管中,我只得到Throwable,没有说明是什么原因造成的。
我想,我可以深入研究DeadLetters后演员的终止,但这似乎是一种嘈杂的方法,因为我必须听所有的死信,并将终止与死信事件流相关。
更新: DeadLetter似乎并不是一种选择。导致死亡的信息甚至没有传到DeadLetters,它只是消失了。
有没有什么机制让我视而不见?
发布于 2015-10-16 16:37:29
根据Akka用户列表上的这条线,在演员监督死亡周期中没有一种机制来实现这一点。此外,文件明确指出,删除了该消息:
信息发生了什么? 如果在处理邮件时抛出异常(即从其邮箱取出并移交给当前行为),则此消息将丢失。重要的是要明白,它没有放回邮箱。因此,如果您想要重新尝试处理一条消息,您需要自己处理它,捕捉异常并重试您的流。
理想的解决方案是使用专用的参与者进行危险操作,并让发起者监视该参与者的死亡,以确定失败。
由于我的场景来自一些被认为是安全的东西,但是其中有一个错误,所以单独的参与者选项应该是在事实之后。为了避免在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
}
}https://stackoverflow.com/questions/33135529
复制相似问题