Search code examples
akkaakka-supervision

Akka and Supervisor Strategies that fallback


I am brand new to Akka but my understanding about the Stop directive is that it is used inside of SupervisorStrategies when the child should be considered permanently out of service, but there is a way to handle the total outage.

If that understanding is correct, then what I would like to do is have some kind of a “backup actor” that should be engaged after the normal/primary child is stopped and used from that point forward as a fallback. For example, say I have a parent actor who has a child actor - Notifier - whose job it is to send emails. If the Notifier truly dies (say, the underlying mail server goes offline), a backup to this actor might be another actor, say, QueueClient, that sends the notification request to a message broker, where the message will be queued up and replayed at a later time.

How can I define such a SupervisorStrategy to have this built in fault tolerance/actor backup inside of it? Please show code examples, its the only way I will learn!


Solution

  • Overriding Supervisor Strategies beyond the default directives is not commonly done, and not really necessary in your case. A solution would be to watch the child actor from the parent, and when the parent finds that the child is stopped, engage the backup actor.

    import akka.actor.SupervisorStrategy.Stop import akka.actor._

    class Parent extends Actor {
    
      var child: ActorRef = context.actorOf(Props[DefaultChild])
      context.watch(child)
    
      def receive = {
        case Terminated(actor) if actor == child => 
          child = context.actorOf(Props[BackupChild])
      }
    
      override def supervisorStrategy = OneForOneStrategy() {
        case ex: IllegalStateException => Stop
      }
    }
    
    class DefaultChild extends Actor {
    
      def receive = { case _ => throw new IllegalStateException("whatever") }
    }
    
    class BackupChild extends Actor {
    
      def receive = { case _ => }
    }