TreyBCollier
TreyBCollier

Reputation: 363

Scala Akka Fault Tolerance/Supervision not working

I am trying to implement fault tolerance within my actor system for my Scala project, to identify errors and handle them. I am using Classic actors. Each supervisor actor has 5 child actors, if one of these child actors fails, I want to restart that actor, and log the error, and as I mentioned, handle the problem that caused this actor to fail.

I implemented a One-For-One SupervisorStrategy in my Supervisor actor class as such:

override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 5, withinTimeRange = 1.minute) {
      case e: ArithmeticException =>
        logger.error(s"Supervisor: $e from $sender; Restarting!")
        Restart
      case e: NullPointerException =>
        logger.error(s"Supervisor: $e from $sender; Restarting!")
        Restart
      case e: IllegalArgumentException =>
        logger.error(s"Supervisor: $e from $sender; Restarting!")
        Restart
      case _: Exception =>
        logger.error(s"Supervisor: Unknown exception from $sender; Escalating!")
        Restart 
    }

I added a throw new NullPointerException in one of the methods I know is called in every actor, as the system never/rarely fails. But, in the log file, I do not get what I expect, but the following:

13:41:19.893 [ClusterSystem-akka.actor.default-dispatcher-21] ERROR akka.actor.OneForOneStrategy - null
java.lang.NullPointerException: null

I have looked at so many examples, as well as the Akka documentation for fault tolerance for both types and classic actors, but I cannot get this to work.

EDIT

After doing some more research, I saw that a potential reason for the error I am getting could be caused by an infinite cycle in the child actor, whereby it throws an error, restarts, throws an error etc.

So I took a different approach, where in the supervisor actor, I added a variable sentError = false, then in one of the supervisor methods that tells the child actors to start working, I added the following:

if(!errorSent){
   errorSent = true
   actor ! new NullPointerException
}

And when a child actor receives an error, they throw it. I took this approach so that this only ever happens once, to avoid the cycle. However, unfortunately this did not change the output, and I still got the error mentioned above.

Upvotes: 0

Views: 140

Answers (0)

Related Questions