2013-03-22 4 views
6

SfondoAkka l'invio di una chiusura con l'attore a distanza

voglio inviare una chiusura ad un attore a distanza. attore remoto dovrebbe eseguire la chiusura sui suoi dati e inviare il risultato. può essere non è consigliabile, ma per l'amor di curiosità che di quello che voglio fare ora

Ma osservo che se una chiusura viene creato come una funzione anonima, si coglie l'oggetto esterno anche e cerca di maresciallo, il che fallisce se l'oggetto esterno non è serializzabile, come in questo caso.

class Client(server: ActorRef) extends Actor { 

    var every = 2 

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

} 

il codice precedente genera un'eccezione durante la chiamata all'attore remoto. ho potuto definire una variabile locale nel metodo preStart()

val every_ = every

e utilizzarlo al posto della variabile membro attore. Ma penso che sia una soluzione alternativa e non una soluzione. e dovrò stare molto attento se la chiusura è un po 'più complessa.

L'alternativa è definire una classe che eredita da Function1[A,B] e inviare le sue istanze come chiusura.

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

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


server ! new Message(new MyFunc(every)) 

Ma questa separa la definizione di chiusura dal luogo viene utilizzato, e sconfigge l'intero scopo di utilizzare un linguaggio funzionale. e rende anche più difficile definire la logica di chiusura.

query specifica

C'è un modo per rinviare la definizione del corpo del Function1.apply e assegnare il corpo di apply quando creo l'istanza di MyFunc da una chiusura definita a livello locale?

ad es.

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

dove every è una variabile locale?

Fondamentalmente voglio combinare i due approcci cioè inviare un oggetto di Function1 verso attore remoto con il corpo di Function1 definito da una funzione anon definita in luogo dove si crea Function1 esempio.

Grazie,

+0

Credo che si sa cosa si sta facendo, ma voglio per essere certi che l'invio di chiusure è considerato una cattiva pratica come spiegato chiaramente nella [documentazione] (http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html) - paragrafo Attore Best practice alinea 3 –

+0

grazie per averlo indicato. in alternativa, posso incapsulare quel comportamento in un attore e crearlo dinamicamente? Detto il comportamento dell'attore in base alla chiusura piuttosto che inviare la chiusura stessa all'attore. – weima

+0

C'è molto che puoi fare ma ho la sensazione che tu stia cercando di implementare la soluzione "sbagliata"/scomoda per un problema specifico. Credo che se modifichi la tua domanda e descrivi cosa stai cercando di ottenere, riceverai risposte migliori su SO –

risposta

3

Certo, si potrebbe inviare un comportamento con l'attore, ma considerata una cattiva pratica, e le vostre domande è una buona risposta su domanda: "perché".

Come sottolineato da BGR, esiste una sezione speciale in documentation su questa domanda, ma non ha alcun esempio.

Quindi, quando si invia una chiusura come messaggio, si invia un ulteriore stato "implicito" con esso. Potrebbe non essere mutabile come detto nella documentazione, ma anche in questo caso può creare problemi.

Il problema con scala qui è che non è un linguaggio strettamente funzionale, è un linguaggio multiparadigm. In altre parole si potrebbe avere il codice in paradigma funzionale fianco a fianco con il codice in stile imperativo.Non ci sono tali problemi in, ad esempio haskell, che è puramente funzionale.

In caso di "query specifica" suggerisco di utilizzare una serie di funzioni predefinite. Questo è l'equivalente completo della variante con chiusure ma con una sintassi bit chatty. Dato che non si genera codice durante il runtime, tutte le funzioni che si usano sono definite in serie limitata e (assomiglia) parametrizzate per valore. Ciò rende il tuo codice non così flessibile come con le chiusure, ma alla fine saranno casi equivalenti.

Così, come un filo conduttore di tutta la mia posta: se hai intenzione di inviare un comportamento con l'attore dovrebbe essere solida roccia atomica (in senso non hanno dipendenze)