【发布时间】: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。
我也使用了一种对所有的策略。所以,基本上,每当重新启动所有演员时,我都会收到很多这样的错误。
可能的解释也就是猜测
在所有actors重新启动后,每个actors的一个新实例被创建,因此没有先前的消息
当actors 作为one-for-all 重新启动时,它们的所有消息都已被处理并且它们的队列是空的。这意味着没有以前的消息
【问题讨论】:
-
为什么不直接使用
OneForOneStrategy呢?如果这些参与者通常是不相关的,那么当其中一个失败时,为什么要重新启动所有参与者呢?我同意这可能是您在preRestart上没有看到以前的消息的原因 -
嗨,大部分演员都是相关的。它们都共享一个套接字,当其中一个失败时我们会创建一个新套接字,因为连接错误是最常见的异常。
-
actor 重新启动时,它会记住邮箱内容。 link
标签: scala playframework akka