1
votes

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

  1. After all actors are restarted a new instance of each actor is created, and thus there is no previous message

  2. 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

1
Why not just use a 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 the preRestartcmbaxter
Hi, most of the actors are related. They all share a socket, and we create a new socket when one of them fails because connection errors are the most common exception.user2668128
when actor is restarted it remembers mailbox content. linkgoral

1 Answers

2
votes

The documentation for preRestart states: "message - optionally the current message the actor processed when failing, if applicable"

I.e. it is only applicable to the failing actor. Not the other ones who are just restarted and not failing.