2014-11-13 5 views
13
documentazione

L'Akka documenta varianti pericolose di utilizzare Props:Che cosa significa "chiudere sopra l'ambito/classe che racchiude"?

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

Poi porta nell'affermare:

Questo metodo non è raccomandato per essere utilizzato all'interno di un altro attore perché incoraggia a chiudere il che racchiude l'ambito, risultante in Puntatori non serializzabili e possibilmente in condizioni di competizione (interruzione dell'incapsulamento dell'attore ).

Qualcuno potrebbe spiegare il significato di "chiusura oltre l'ambito di applicazione"? Ho cercato dappertutto e non ho trovato nulla. Grazie.

risposta

14

È un po 'complicato vedere in questo esempio che lo new Actor viene passato come un cosiddetto parametro "per nome". Pensalo come se fosse trasformato in una funzione di tipo () => Actor. Questa funzione verrà chiamata ogni volta che l'attore verrà (ri) creato dal supervisore durante un riavvio.

Il problema è che questa funzione è una "chiusura" (molto facile per Google; "). E.g val f = (a: Int) => a + x. Da dove viene il x? Viene dall'ambito circostante. La funzione litetal, assegnata a f è denominata "open term". In runtime, la funzione letterale diventa un valore di funzione (che è un modo elegante per dire "oggetto"), che quando viene eseguito chiude il termine aperto, mentre acquisisce tutto ciò che si trova nell'ambiente circostante. Ecco da dove viene il nome "chiusura".

Le chiusure sono molto molto utili, ma bisogna stare attenti a ciò che si chiude. A volte x è un def o dio proibisce uno var, che porta a risultati imprevedibili per f, perché non si ha il controllo sul tempo quando f verrà chiamato/eseguito. Provalo!

Due paterns anti-molto comuni in Akka sono/sono stati:

  1. Chiusura sopra (l'esterno) di riferimento this durante la creazione di un attore da una classe interna.
  2. Chiudere su def sender quando si risponde a un messaggio con un futuro.

ti ho dato un po 'di termini di fantasia a Google di proposito, btw;)

Saluti e felice di codifica

+2

Grazie. Ricca spiegazione – Peter

7

Come supplemento alla risposta multa @ di agilesteel, alcune referenze:

Spiega quali sono le chiusure: Programmazione in Scala, 8.7, chiusure

spiega perché chiusure possono causare problemi di serializzazione: SIP-21 - Spores

E qui un esempio di codice di creare un oggetto puntelli non serializzabile causa di chiusura su un oggetto non serializzabile, sull'esempio in SIP-21:

case class Helper(name: String) 

object MyNonserializableObject { 

    val helper = Helper("the helper") 

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

Anche se helper sé è serializzabile, la "nuova MyActor (helper)" è passato per nome e così cattura this.helper, e this non è serializzabile.

Si può vedere che il parametro attore è passato dal nome dalla firma del metodo Propsapply dove c'è un ⇒ nel parametro creator:

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

Grazie per il tuo contributo. – Peter