23

在官方akka 2.0.4 文档中它说:

Actor 重启只替换实际的 Actor 对象;邮箱的内容不受重启的影响,所以在 postRestart 钩子返回后会继续处理消息。触发异常的消息将不会再收到。重新启动时发送给actor的任何消息都将像往常一样排队到其邮箱中。

假设我有一条消息导致我的演员重新启动。它不再在邮箱中,因此将不会被取代它的演员处理。如果我无论如何都希望演员处理此消息(假设在这种情况下顺序无关紧要),那么演员在重新启动时将消息发送给自己会是一个坏主意吗?

一些(伪)代码来说明我的意思:

class ResendingActor extends Actor {
  var curMessage: Option[MyMessage] = None
  def receive = {
    case MyMessage(x) => {
      curMessage = Some(MyMessage(x))
      /* processing */
      curMessage = None
    }
  }
  override def preRestart(reason: Throwable, message: Option[Any]) {
    curMessage match {
      case Some(x) => self ! x
      case None => ;
    }
  }
}

这样,在重新启动之前未由 Actor 处理的消息将被推送到新 Actor 的队列末尾。

所以我的问题是:有什么理由我不应该这样做吗?

我唯一能想到的是,如果消息由于某种原因格式错误,它永远不会离开系统并导致actor定期重启......

4

1 回答 1

17

您已经在 preRestart 中收到了失败消息(请参阅:消息:Option[Any]),因此无需自己隐藏它。是的,将它重新发送给自己是完全可以的,但要小心与此相结合的无限重启,因为你很可能最终会收到一条永远不会被丢弃的消息。

于 2012-11-25T01:32:35.777 回答