2013-03-22 9 views
6

Hintergrundakka einen Verschluss zu entfernten Schauspieler Senden

Ich möchte eine Schließung zu einem Remote-Schauspieler senden. Remote-Akteur sollte die Schließung seiner Daten ausführen und das Ergebnis zurücksenden. Vielleicht ist es nicht ratsam ist, aber aus Gründen der Neugier, die ich jetzt

tun wollen, aber ich beachten, dass, wenn eine Schließung als eine anonyme Funktion erstellt wird, ist es das äußere Objekt erfasst auch und versucht, sie zu ordnen, die schlägt fehl, wenn das äußere Objekt wie in diesem Fall nicht serialisierbar ist.

class Client(server: ActorRef) extends Actor { 

    var every = 2 

    override def preStart() = { 
    println("client started. sending message....") 
    server ! new Message((x) => x % every == 0) 
    } 

} 

Der obige Code generiert Ausnahme beim Aufruf des Remote Actor. Ich könnte eine lokale Variable in dem Verfahren preStart()

val every_ = every

und es verwenden, anstelle der Schauspieler Elementvariable definieren. Aber ich denke, es ist ein Workaround, keine Lösung. und ich muss sehr vorsichtig sein, wenn die Schließung etwas komplexer ist.

Alternative besteht darin, eine Klasse zu definieren, die von Function1[A,B] erbt und ihre Instanzen als Closure sendet.

Aber dies trennt die Definition der Schließung von dem Ort, an dem es verwendet wird, und vereitelt den ganzen Zweck der Verwendung einer funktionalen Sprache. und macht auch die Definition der Abschlusslogik schwieriger.

Spezifische Abfrage

Gibt es eine Weise, die ich den Körper der Function1.apply definieren, verschieben kann und den Körper von apply zuweisen, wenn ich die Instanz von MyFunc von einem lokal definierten Verschluss schaffen?

z.B.

server ! new Message(new MyFunc(every){ // not valid scala code 
    x % every == 0 
}) 

wo ist every eine lokale Variable?

Grundsätzlich möchte ich die beiden Ansätze kombinieren, das heißt ein Objekt von Function1 über mit dem Körper Function1 durch eine Anon Funktion anstelle definiert definiert Remote-Akteur senden, wo Function1 Instanz erstellt wird.

Danke,

+0

Ich denke, Sie wissen, was Sie tun, aber ich will um sicherzustellen, dass Sie wissen, dass das Versenden von Schließungen als eine schlechte Praxis angesehen wird, wie in der [Dokumentation] (http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html) - Absatz Actor deutlich erklärt Best Practices alinea 3 –

+0

danke für den Hinweis. Alternativ kann ich dieses Verhalten in einem Akteur einkapseln und dynamisch erstellen? diktieren das Verhalten des Schauspielers basierend auf der Schließung, anstatt die Schließung selbst an den Schauspieler zu senden. – weima

+0

Es gibt viel, was Sie tun können, aber ich habe das Gefühl, dass Sie versuchen, die "falsche"/peinliche Lösung für ein bestimmtes Problem zu implementieren. Ich glaube, wenn Sie Ihre Frage bearbeiten und beschreiben, was Sie erreichen möchten, erhalten Sie bessere Antworten auf SO –

Antwort

3

Natürlich könnten Sie Verhalten Schauspieler schicken, aber es als eine schlechte Praxis, und Ihre Fragen sind auf Frage eine gute Antwort sein: „Warum“.

Wie BGR darauf hingewiesen, gibt es spezielle Abschnitt in documentation zu dieser Frage, aber es hat kein Beispiel.

Also, wenn Sie eine Schließung als Nachricht senden Sie senden einige zusätzliche "impliziten" Zustand mit ihm. Es könnte nicht wie in der Dokumentation beschrieben veränderbar sein, aber selbst in diesem Fall kann es Probleme verursachen.

Das Problem mit scala hier ist, dass es nicht streng funktionale Sprache - es ist multiparadigm Sprache. Mit anderen Worten, Sie könnten Code im funktionalen Paradigma neben Code im imperativen Stil haben.Solche Probleme gibt es zum Beispiel in Haskell, das rein funktional ist.

Im Falle Ihrer "spezifischen Abfrage" empfehle ich Ihnen, vordefinierte Funktionen zu verwenden. Dies ist volles Äquivalent der Variante mit Schließungen, aber mit einer etwas gesprächigen Syntax. Da Sie während der Laufzeit keinen Code generieren, sind alle Funktionen, die Sie verwenden, in limitierter Menge definiert und (wie es aussieht) nach Werten parametrisiert. Dies macht Ihren Code nicht so flexibel wie bei Schließungen, aber am Ende wird es gleichwertige Fälle sein.

So, wie ein roter Faden von allen meinen Post: Wenn Sie Verhalten Schauspieler gehen senden sollte es rocken solide sein Atom (in der Bedeutung haben keine Abhängigkeiten)

Verwandte Themen