Tratamento de falhas em atores Akka

Eu tenho um exemplo muito simples em que eu tenho um ator (SimpleActor) que executam uma tarefa periódica enviando uma mensagem para si. A mensagem está agendada no construtor para o ator. No caso normal (ou seja, sem falhas) tudo funciona bem.

Mas e se o ator tiver que lidar com falhas. Eu tenho outro ator (SimpleActorWithFault) Este ator pode ter falhas. Nesse caso, eu mesmo estou gerando um, lançando uma exceção. Quando ocorre uma falha (ou seja,SimpleActorWithFault lança uma exceção) é reiniciado automaticamente. No entanto, essa reinicialização atrapalha o agendador dentro do Actor, que não funciona mais conforme o esperado. E se as falhas acontecem com rapidez suficiente, gera um comportamento mais inesperado.

Minha pergunta é qual é a maneira preferida de lidar com falhas nesses casos? Eu sei que posso usarTry blocos para lidar com exceções. Mas e se eu estiver estendendo outro ator em que não posso colocar um Try na superclasse ou, em alguns casos, quando eu sou uma falha, exceto no ator.

import akka.actor.{Props, ActorLogging}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import akka.actor.Actor

case object MessageA

case object MessageToSelf


class SimpleActor extends Actor with ActorLogging {

  //schedule a message to self every second
  context.system.scheduler.schedule(0 seconds, 1 seconds, self, MessageToSelf)

  //keeps track of some internal state
  var count: Int = 0

  def receive: Receive = {
    case MessageA => {
      log.info("[SimpleActor] Got MessageA at %d".format(count))
    }
    case MessageToSelf => {
      //update state and tell the world about its current state 
      count = count + 1
      log.info("[SimpleActor] Got scheduled message at %d".format(count))

    }
  }

}


class SimpleActorWithFault extends Actor with ActorLogging {

  //schedule a message to self every second
  context.system.scheduler.schedule(0 seconds, 1 seconds, self, MessageToSelf)

  var count: Int = 0

  def receive: Receive = {
    case MessageA => {
      log.info("[SimpleActorWithFault] Got MessageA at %d".format(count))
    }
    case MessageToSelf => {
      count = count + 1
      log.info("[SimpleActorWithFault] Got scheduled message at %d".format(count))

      //at some point generate a fault
      if (count > 5) {
        log.info("[SimpleActorWithFault] Going to throw an exception now %d".format(count))
        throw new Exception("Excepttttttiooooooon")
      }
    }
  }

}


object MainApp extends App {
  implicit val akkaSystem = akka.actor.ActorSystem()
  //Run the Actor without any faults or exceptions 
  akkaSystem.actorOf(Props(classOf[SimpleActor]))

  //comment the above line and uncomment the following to run the actor with faults  
  //akkaSystem.actorOf(Props(classOf[SimpleActorWithFault]))

}

questionAnswers(2)

yourAnswerToTheQuestion