2016-02-11 10 views
5

Wenn ich einen Logging Schauspieler erstellen wie soWird ein ActorRef aktualisiert, wenn der zugehörige Actor vom Supervisor neu gestartet wird?

val logger: ActorRef = 
    actorSystem.actorOf(Props(new Logger())) 

und der Logger neu gestartet wird aufgrund einer Ausnahme, mein Logger nicht mehr auf der Festplatte geschrieben.

Ich hatte das Senden von Nachrichten logger ! msg

Bin ich in der Annahme richtig, dass die ActorRef nicht aktualisiert, wenn der Supervisor meine Protokollierung Schauspieler neu gestartet?

Antwort

8

ActorRef sollte von Akka korrekt aktualisiert werden, um auf die neue Instanz eines Schauspielers zu zeigen. Die docs klar zum Ausdruck, dass:

Ein Verweis zeigt auf einem abgeschlossenen Schauspieler nicht vergleichen gleich einen Verweis zeigt auf eine andere (neu erstellt) Schauspieler mit dem gleichen Pfad. Beachten Sie, dass ein Neustart eines Aktors durch einen Fehler immer noch bedeutet, dass es ist die gleiche Schauspieler Inkarnation, d. H. Ein Neustart ist nicht sichtbar für der Verbraucher des ActorRef.

Auch here:

Wenn actorOf() aufgerufen wird, sie eine Verkörperung des Darstellers zuordnet von den Stützen geführt auf den gegebenen Pfad beschrieben. Eine Schauspieler-Inkarnation wird durch den Pfad und eine UID identifiziert. Bei einem Neustart wird nur die Instanz Actor ausgetauscht, die von den Requisiten definiert wurde, aber die Inkarnation und damit die UID bleibt gleich.

Der Lebenszyklus einer Inkarnation endet, wenn der Aktor gestoppt wird. Unter werden an diesem Punkt die entsprechenden Lebenszyklusereignisse aufgerufen und Aktoren werden über die Beendigung informiert. Nachdem die Inkarnation gestoppt wurde, kann der Pfad erneut verwendet werden, indem ein Actor mit actorOf() erstellt wird. In diesem Fall wird der Name der neuen Inkarnation sein, derselbe wie der vorherige, aber die UIDs werden sich unterscheiden. ...

Ein ActorRef stellt immer eine Inkarnation (Pfad und UID) nicht nur einen bestimmten Weg. Wenn also ein Schauspieler gestoppt wird und ein neuer mit gleichen Namen erstellt wird, wird ein ActorRef der alten Inkarnation nicht auf den neuen zeigen.

Das ist einer der Hauptvorteile der Verwendung von ActorRef s, sonst wäre es viel unbequemer mit Schauspielern zu arbeiten.

Sie müssen Ihre Supervisor-Strategie überprüfen und sicherstellen, dass der Aktor tatsächlich neu gestartet wird. Standardstrategie ist:

final val defaultStrategy: SupervisorStrategy = { 
    def defaultDecider: Decider = { 
    case _: ActorInitializationException ⇒ Stop 
    case _: ActorKilledException   ⇒ Stop 
    case _: Exception     ⇒ Restart 
    } 
    OneForOneStrategy()(defaultDecider) 
} 

Wenn Sie also ein Exception Ihre Schauspieler erhalten wird neu gestartet werden und ActorRef gültig sein sollte, aber wenn man andere Arten von Throwable bekommen, dann wird es gestoppt werden und ActorRef ungültig wird.

+1

Danke. Das erklärt es wirklich gut. Ich möchte nur hinzufügen, dass beim Neustart eines Actors die Verarbeitung der Nachricht, die den Neustart verursacht hat, nicht abgeschlossen ist. In meinem Fall hat der Schauspieler niemals eine Nachricht an sich selbst gesendet, um den nächsten Job auszulösen. – kliew

+0

Danke für das Followup @ kliew. Ich war neugierig auf den Grund, warum es in Ihrem Fall nicht wie erwartet funktionierte. –

+0

Wenn du innerhalb des Akteursystems bist, kannst du den AkteurReuf sehen. Aber wenn du einen ActorRef von außen erhalten möchtest, wie würdest du das auf dem neuesten Stand halten? –