2013-03-22 14 views
6

TleAkka wysyłanie zamknięcie do zdalnego aktor

chcę wysłać zamknięcie do zdalnego aktor. zdalny aktor powinien uruchomić zamknięcie swoich danych i odesłać wynik. Może to nie jest wskazane, ale z ciekawości, która jest chcę teraz zrobić

Ale ja zauważyć, że jeśli zamknięcie jest tworzony jako anonimowej funkcji, to chwyta zewnętrzną obiektu także i stara się je zebrać, który kończy się niepowodzeniem, jeśli zewnętrzny obiekt nie jest możliwy do serializacji, tak jak w tym przypadku.

class Client(server: ActorRef) extends Actor { 

    var every = 2 

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

} 

Powyższy kod generuje wyjątek podczas wywoływania zdalnego aktora. mogę zdefiniować zmienną lokalną w sposobie preStart()

val every_ = every

i używać go w miejsce zmiennej składowej aktor. Ale uważam, że to obejście, a nie rozwiązanie. i będę musiał bardzo uważać, jeśli zamknięcie jest nieco bardziej skomplikowane.

Alternatywą jest zdefiniowanie klasy dziedziczącej z Function1[A,B] i wysłanie jej wystąpień jako zamknięcia.

class MyFunc(every : Int) extends Function1[Int,Boolean] with Serializable { 

    def apply(v1 :Int) : Boolean = { 
    v1 % every == 0 
    } 
} 


server ! new Message(new MyFunc(every)) 

Ale to oddziela definicję zamknięcia od miejsca, w którym jest używany, i pokonuje cały cel używania języka funkcjonalnego. a także utrudnia definiowanie logiki zamknięcia.

Specific Query

Czy istnieje sposób mogę odroczyć definiowania ciało Function1.apply i przypisać ciało apply gdy tworzę instancję MyFunc z lokalnie zdefiniowanej zamknięcia?

np.

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

gdzie every jest zmienną lokalną?

zasadzie chcę połączyć dwa podejścia tj wysłać przedmiot Function1 nad zdalnym aktora z ciałem Function1 zdefiniowanej przez funkcję anon określonym w miejscu gdzie Function1 instancja jest tworzony.

Dzięki,

+0

Chyba wiesz, co robisz, ale chcę aby upewnić się, że wiesz, że wysyłanie zamknięć jest uważane za niewłaściwą praktykę, jak to wyraźnie wyjaśniono w [dokumentacji] (http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html) - paragraph Actor Najlepsze praktyki alinea 3 –

+0

dzięki za wskazanie. alternatywnie czy mogę hermetyzować to zachowanie u aktora i tworzyć je dynamicznie? tj. dyktować zachowanie aktora w oparciu o zamknięcie, zamiast wysyłać samego aktora. – weima

+0

Jest wiele rzeczy, które możesz zrobić, ale mam wrażenie, że próbujesz wdrożyć "niewłaściwe"/niezręczne rozwiązanie określonego problemu. Wierzę, że jeśli edytujesz swoje pytanie i opisujesz, co próbujesz osiągnąć, uzyskasz lepsze odpowiedzi na SO –

Odpowiedz

3

Oczywiście, można wysłać do zachowania aktora, ale uważane za złą praktyką, a Twoje pytania to dobra odpowiedź na pytanie: „dlaczego”.

BGR zwrócił uwagę, że w tym pytaniu znajduje się specjalna sekcja w numerze documentation, ale nie ma ona żadnego przykładu.

Kiedy wysyłasz zamknięcie jako wiadomość, przesyłasz z nim dodatkowy "niejawny" stan. Nie można go zmienić tak, jak to opisano w dokumentacji, ale nawet w tym przypadku może powodować problemy.

Problem ze scala polega na tym, że nie jest to język ściśle funkcjonalny - jest to język wielowymiarowy. Innymi słowy, możesz mieć kod w funkcjonalnym paradygmacie obok kodu w stylu imperatywnym.Nie ma takich problemów w, na przykład, haskell, który jest czysto funkcjonalny.

W przypadku Twojego "konkretnego zapytania" proponuję użyć zestawu predefiniowanych funkcji. Jest to pełny odpowiednik wariantu z zamknięciami, ale z nieco rozmowną składnią. Ponieważ nie generujesz kodu w czasie wykonywania, wszystkie używane funkcje są zdefiniowane w ograniczonym zestawie i (wygląda) parametryzowane według wartości. To sprawia, że ​​twój kod nie jest tak elastyczny, jak przy zamknięciach, ale w końcu będzie to równorzędny przypadek.

Więc, jako motyw przewodni całego mojego postu: jeśli masz zamiar wysłać zachowanie się aktora powinien być solidny atomowej (w rozumieniu nie ma żadnych zależności)

Powiązane problemy