I have some actors that when their preRestart() is invoked, the "message" is None. I don't understand why this is the case.
Context
My application is a Play web application that uses Akka. My error handling strategy is to send an error notification to the origin of the request, so details can be sent down to the user. I do this by hooking into preRestart() as follows:
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
}
Problem
In my logs, I am seeing a lot of the "Attempted to notify requester but no previous message" error logs. Usually it occurs for all the actors in my system. This is likely because I have one top-level actor, which is responsible for all the other actors (they are all children).
In the logs, the reason parameter does contain a throwable, though.
I am also using a one-for-all strategy. So, basically, whenever all the actors are restarted, I get lots of these errors.
Possible Explanations aka guesses
After all actors are restarted a new instance of each actor is created, and thus there is no previous message
When actors are restarted as one-for-all, all of their messages have been processed and their queue is empty. This means that there is no previous message
OneForOneStrategy
instead? If these actors are generally unrelated, then why restart all of them when one of them fails? I agree that this is probable the reason why you see no previous message on thepreRestart
– cmbaxter