首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >捕捉杀死一个演员的信息

捕捉杀死一个演员的信息
EN

Stack Overflow用户
提问于 2015-10-14 21:02:16
回答 1查看 175关注 0票数 3

当接收者因该消息而死亡时,我试图回复消息的发送方。如果我Restart的演员失败,我会得到

代码语言:javascript
复制
preRestart(reason: Throwable, message: Option[Any])

但现在我决心重新开始。

如果我Stop演员,我只会得到

代码语言:javascript
复制
postStop()

不知道是什么阻止了我自己。

同时,在主管中,我只得到Throwable,没有说明是什么原因造成的。

我想,我可以深入研究DeadLetters后演员的终止,但这似乎是一种嘈杂的方法,因为我必须听所有的死信,并将终止与死信事件流相关。

更新: DeadLetter似乎并不是一种选择。导致死亡的信息甚至没有传到DeadLetters,它只是消失了。

有没有什么机制让我视而不见?

EN

回答 1

Stack Overflow用户

发布于 2015-10-16 16:37:29

根据Akka用户列表上的这条线,在演员监督死亡周期中没有一种机制来实现这一点。此外,文件明确指出,删除了该消息:

信息发生了什么? 如果在处理邮件时抛出异常(即从其邮箱取出并移交给当前行为),则此消息将丢失。重要的是要明白,它没有放回邮箱。因此,如果您想要重新尝试处理一条消息,您需要自己处理它,捕捉异常并重试您的流。

理想的解决方案是使用专用的参与者进行危险操作,并让发起者监视该参与者的死亡,以确定失败。

由于我的场景来自一些被认为是安全的东西,但是其中有一个错误,所以单独的参与者选项应该是在事实之后。为了避免在try/catch中包装所有代码路径,但能够保护更复杂和关键的流,我最终为receive创建了一个包装器,让我拦截异常:

代码语言:javascript
复制
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)
    }
}

我可以用它来挑选这样的演员:

代码语言:javascript
复制
def receive = SafeReceive {
  case ... => ...
} {
  msg => {
    case e: Exception =>
      sender ! OperationFailed(msg, e)
      throw e
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33135529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档