当接收演员因该消息而死亡时,我正在尝试回复消息的发送者。如果我Restart
失败的演员我得到了
preRestart(reason: Throwable, message: Option[Any])
但现在我决定重新启动。
如果我是Stop
演员,我只能
postStop()
不知道是什么阻止了我自己。
与此同时,在主管中,我只得到Throwable
并且没有任何迹象表明它是什么原因。
我想,我可以通过DeadLetters
帖子演员终止,但这似乎是一个嘈杂的方法,因为我必须听所有死信,并在某处将终止与deadletter事件流相关联
更新: DeadLetter
似乎不是一个选项。导致死亡的消息甚至没有发送到DeadLetters,它只是消失了。
我有一种机制可以忽略吗?
答案 0 :(得分:1)
根据Akka用户名单上的this thread,行动者监督死亡周期中没有一种机制可以实现这一目标。此外,文档明确声明消息已被删除:
如果在处理邮件时抛出异常(即从邮箱中取出并移交给当前行为),则此邮件将丢失。重要的是要了解它没有放回邮箱。因此,如果要重试处理消息,则需要通过捕获异常并重试流程来自行处理。
理想的解决方案是使用专用的参与者进行危险的操作,并让发起者监视该参与者的死亡以确定失败。
由于我的场景来自于被认为是 safe 的内容,但其中有一个错误,因此单独的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
}
}