2014-11-13 11 views
13

Die Akka Dokumentation dokumentiert gefährliche Varianten Props mit:Was bedeutet "über den umschließenden Bereich/Klasse schließen"?

// NOT RECOMMENDED within another actor: 
// encourages to close over enclosing class 
val props7 = Props(new MyActor) 

führt dann auf die besagt:

Diese Methode wird nicht empfohlen, in einem anderen Akteur verwendet werden, weil es die schließen über ermutigt umschließenden Umfang, was zu nicht-serialisierbaren Requisiten und möglicherweise Rennbedingungen führt (die Aktorkapselung durchbrechend).

Könnte jemand bitte die Bedeutung von "Schließen des umschließenden Bereichs" erklären? Ich habe überall gesucht und nichts gefunden. Vielen Dank.

Antwort

14

In diesem Beispiel ist es etwas schwierig zu sehen, dass der new Actor als so genannter "by name" -Parameter übergeben wird. Stellen Sie sich vor, dass es in eine Funktion des Typs () => Actor umgewandelt wird. Diese Funktion wird jedes Mal aufgerufen, wenn der Akteur bei einem Neustart von seinem Supervisor neu angelegt wird.

Das Problem ist, dass diese Funktion eine "closure" (sehr einfach zu Google;)) ist, was bedeutet, dass es alles im umgebenden Bereich erfasst und merkt (manchmal, aber sehr selten als "Stack-Ripping" bezeichnet) "). ZB val f = (a: Int) => a + x. Woher kommt die x? Es kommt von dem umgebenden Umfang. Die Funktion liteal, die f zugewiesen ist, wird als "offener Begriff" bezeichnet. Zur Laufzeit wird das Funktionsliteral zu einem Funktionswert (das ist eine originelle Art, "Objekt" zu sagen), der bei der Ausführung den offenen Term schließt, während alles im umgebenden Bereich erfasst wird. Von dort kommt der Name "closure".

Verschlüsse sind sehr, sehr nützlich, aber Sie müssen vorsichtig sein, was Sie zu schließen. Manchmal x ist ein def oder Gott bewahre eine var, die zu unvorhersehbaren Ergebnissen für f führt, weil Sie keine Kontrolle über die Zeit haben, wenn f aufgerufen/ausgeführt wird. Versuch es!

Zwei sehr häufig anti paterns in Akka sind/waren:

  1. Schließen über (die äußere) this Referenz, wenn ein Schauspieler von einer inneren Klasse zu schaffen.
  2. Schließen über def sender beim Antworten auf eine Nachricht mit Zukunft.

Ich habe Ihnen ein paar ausgefallene Begriffe zu Google absichtlich, btw;)

Prost und glücklich Codierung

+2

Dank. Reiche Erklärung. – Peter

7

Als Ergänzung zu @ agilesteel ist in Ordnung Antwort, einige Referenzen:

Erklärt, welche Verschlüsse sind: Programmierung in Scala, 8.7, Verschlüsse

Erklärt, warum Verschlüsse Serialisierung Probleme verursachen können: SIP-21 - Spores

Und hier ist ein Codebeispiel ein Props Objekt zu schaffen, die wegen der Schließung über einen nicht serialisierbaren Objekt nicht serialisierbar ist, bezogen auf das Beispiel in SIP-21:

case class Helper(name: String) 

object MyNonserializableObject { 

    val helper = Helper("the helper") 

    val props7 = Props(new MyActor(helper)) 
} 

obwohl helper selbst serialisierbar ist, das "neue MyActor (Helfer)" wird von Namen übergeben und so fängt this.helper und this ist nicht serialisierbar.

Sie können sehen, dass der Schauspieler Parameter von Namen von der Unterzeichnung der Propsapply Methode übergeben wird, wo ein ⇒ dort im creator Parameter ist:

def apply[T <: Actor](creator: ⇒ T)(implicit arg0: ClassTag[T]): Props 
+0

Danke für Ihren Beitrag. – Peter