【问题标题】:Akka - Actor preStart has no previous messageAkka - Actor preStart 没有以前的消息
【发布时间】:2014-08-19 11:50:34
【问题描述】:

我有一些演员,当他们的 preRestart() 被调用时,“消息”是无。我不明白为什么会这样。

上下文

我的应用程序是一个使用 Akka 的 Play 网络应用程序。我的错误处理策略是向请求的来源发送错误通知,因此可以将详细信息发送给用户。我通过如下方式连接到 preRestart() 来做到这一点:

trait NotifyRequesterErrorHandling { this: Actor with ActorLogging =>

  override def preRestart(reason: Throwable, message: Option[Any]) {
    notifyRequester(message, reason)
  }

  protected def notifyRequester(message: Option[Any], reason: Throwable) {
    message match {
      case Some(m) =>
        val who = getRequester(m)
        who ! SearchError(reason, m)
      case None =>
        val error = if (reason == null) "No exception" else reason toString()
        ReportError("NotificationError", Some(reason), "", s"${this.context.self.path}: Attempted to notify requester but no previous message")
    }
  }

  def getRequester(message: Any): ActorRef

}

问题

在我的日志中,我看到很多“尝试通知请求者但没有以前的消息”错误日志。通常它发生在我系统中的所有参与者身上。这可能是因为我有一个顶级演员,负责所有其他演员(他们都是孩子)。

在日志中,reason 参数确实包含一个 throwable。

我也使用了一种对所有的策略。所以,基本上,每当重新启动所有演员时,我都会收到很多这样的错误。

可能的解释也就是猜测

  1. 在所有actors重新启动后,每个actors的一个新实例被创建,因此没有先前的消息

  2. 当actors 作为one-for-all 重新启动时,它们的所有消息都已被处理并且它们的队列是空的。这意味着没有以前的消息

【问题讨论】:

  • 为什么不直接使用OneForOneStrategy呢?如果这些参与者通常是不相关的,那么当其中一个失败时,为什么要重新启动所有参与者呢?我同意这可能是您在 preRestart 上没有看到以前的消息的原因
  • 嗨,大部分演员都是相关的。它们都共享一个套接字,当其中一个失败时我们会创建一个新套接字,因为连接错误是最常见的异常。
  • actor 重新启动时,它会记住邮箱内容。 link

标签: scala playframework akka


【解决方案1】:

preRestart 的文档指出:“消息 - 可选地,演员在失败时处理的当前消息,如果适用的话”

即它仅适用于失败的演员。不是其他刚刚重新启动并且没有失败的人。

【讨论】:

    猜你喜欢
    • 2019-08-20
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    相关资源
    最近更新 更多