Обработка ошибок в актерах Akka

У меня очень простой пример, где у меня есть актер (SimpleActor) которые выполняют периодическую задачу, отправляя сообщение себе. Сообщение запланировано в конструкторе для актера. В обычном случае (т.е. без сбоев) все работает нормально.

Но что, если Актер столкнется с ошибками? У меня другой актер (SimpleActorWithFault). У этого актера могут быть недостатки. В этом случае я сам генерирую один, генерируя исключение. Когда происходит сбой (т.е.SimpleActorWithFault выдает исключение) он автоматически перезапускается. Однако этот перезапуск портит планировщик внутри Actor, который больше не работает как исключение. И если ошибки происходят достаточно быстро, это порождает более неожиданное поведение.

Мой вопрос: каков предпочтительный способ устранения неисправностей в таких случаях? Я знаю, что могу использоватьTry блоки для обработки исключений. Но что, если я расширяю другого актера, где я не могу поместить Try в суперкласс, или в случае, если у меня есть исключенная ошибка, происходит в актере.

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]))

}

Ответы на вопрос(2)

Ваш ответ на вопрос