Umgang mit Fehlern in Akka-Darstellern

Ich habe ein sehr einfaches Beispiel, wo ich einen Schauspieler habe (SimpleActor), die eine periodische Aufgabe ausführen, indem sie eine Nachricht an sich selbst senden. Die Nachricht wird im Konstruktor für den Akteur eingeplant. Im Normalfall (d. H. Ohne Fehler) funktioniert alles einwandfrei.

Aber was ist, wenn der Schauspieler mit Fehlern umgehen muss? Ich habe einen anderen Schauspieler (SimpleActorWithFault). Dieser Schauspieler könnte Fehler haben. In diesem Fall generiere ich selbst eine Ausnahme. Wenn ein Fehler auftritt (d. H.SimpleActorWithFault löst eine Ausnahme aus) wird automatisch neu gestartet. Dieser Neustart bringt jedoch den Scheduler im Actor durcheinander, der nicht mehr wie vorgesehen funktioniert. Und wenn die Fehler schnell genug auftreten, führt dies zu unerwartetem Verhalten.

Meine Frage ist, wie in solchen Fällen mit Fehlern umgegangen werden soll. Ich weiß, dass ich es gebrauchen kannTry Blöcke zur Behandlung von Ausnahmen. Aber was ist, wenn ich einen anderen Schauspieler verlängere, bei dem ich keinen Versuch in die Superklasse stecken kann, oder in einem Fall, bei dem ich einen Ausnahmefehler im Schauspieler habe?

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

}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage