Ich habe Akka Supervisor Strategy verwendet, um Business-Logik-Ausnahmen zu behandeln.Akka Supervisor-Strategie - Korrekter Anwendungsfall
Als ich eine der berühmtesten Scala-Blogserien Neophyte las, fand ich ihn einen anderen Zweck für das, was ich schon immer gemacht habe.
Beispiel:
Lassen Sie uns sagen, dass ich ein HttpActor haben, die eine externe Ressource wenden sollte und falls es unten ist, werde ich eine Ausnahme, denn jetzt ein ResourceUnavailableException
.
Wenn mein Supervisor das fängt, werde ich einen Neustart auf meinem HttpActor aufrufen, und in meinem HttpActor preRestart
Methode werde ich eine schedulerOnce
anrufen, um das zu versuchen.
Der Schauspieler:
class HttpActor extends Actor with ActorLogging {
implicit val system = context.system
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
log.info(s"Restarting Actor due: ${reason.getCause}")
message foreach { msg =>
context.system.scheduler.scheduleOnce(10.seconds, self, msg)
}
}
def receive = LoggingReceive {
case g: GetRequest =>
doRequest(http.doGet(g), g.httpManager.url, sender())
}
Ein Betreuer:
class HttpSupervisor extends Actor with ActorLogging with RouterHelper {
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 5) {
case _: ResourceUnavailableException => Restart
case _: Exception => Escalate
}
var router = makeRouter[HttpActor](5)
def receive = LoggingReceive {
case g: GetRequest =>
router.route(g, sender())
case Terminated(a) =>
router = router.removeRoutee(a)
val r = context.actorOf(Props[HttpActor])
context watch r
router = router.addRoutee(r)
}
}
Was hier ist der Punkt?
Wenn meine doRequest
Methode die ResourceUnavailableException
auslöst, wird der Supervisor das bekommen und den Aktor neu starten, so dass er die Nachricht nach einiger Zeit erneut senden muss, laut dem Scheduler. Die Vorteile, die ich sehe, ist die Tatsache, dass ich kostenlos die Anzahl der Wiederholungen und eine nette Art, die Ausnahme selbst zu behandeln, bekomme.
Jetzt im Blog suchen, zeigt er einen anderen Ansatz, falls Sie einen erneuten Versuch Sachen benötigen, nur Meldungen wie diese zu senden:
def receive = {
case EspressoRequest =>
val receipt = register ? Transaction(Espresso)
receipt.map((EspressoCup(Filled), _)).recover {
case _: AskTimeoutException => ComebackLater
} pipeTo(sender)
case ClosingTime => context.system.shutdown()
}
Hier bei AskTimeoutException
der Future
, er Rohre das Ergebnis als ein ComebackLater
Objekt, das er dies tun wird Griff: Für mich
case ComebackLater =>
log.info("grumble, grumble")
context.system.scheduler.scheduleOnce(300.millis) {
coffeeSource ! EspressoRequest
}
das ist ziemlich viel, was Sie mit der Strategie Supervisor tun können, aber in eine manuell Art und Weise, mit eingebauten nicht in der Anzahl der Wiederholungen Logik.
Was ist der beste Ansatz hier und warum? Ist mein Konzept der Akka-Supervisor-Strategie völlig falsch?