繁体   English   中英

捕获杀死演员的消息

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM