2013-06-03 13 views
15

Ho un attore che alla ricezione di un messaggio, cerca nel file system un file e restituisce il percorso completo del file.mittente all'interno di un futuro

Per mantenerlo asincrona, ho fatto:

def receive ={ 
case s:String => { 

    val f = future{ 
     val ans = search(s) 
     println("Input Request: "+s+" output:"+ans+" "+sender.path) 
    } 
    f.onComplete{ 
    case Success(x) => sender ! x 
    case Failure(y) => println("Could not complete it") 
    } 

} 

ma ho osservato che restituisce il messaggio al akka://FileSystem/deadLetters e non il sender. La documentazione dice che:

Valido solo per l'attore stesso, quindi non chiuderlo sopra e * pubblicarlo su altri thread!

Quindi vuol dire che dovrò necessariamente mantenerlo sincrono? C'è un altro modo?

+0

Perché utilizzare un futuro? È un'operazione di I/O (e quindi possibilmente di blocco), quindi metti l'attore sul dispatcher blocking-io. Se è necessario cercare più file contemporaneamente, avere più istanze in esecuzione. –

risposta

32

si stanno facendo un errore molto comune di "chiusura sopra stato mutevole". La chiusura che passi a onComplete non fa una copia di this.sender, quindi quando il tuo onComplete viene chiamato, stai inviando il messaggio a qualsiasi cosa a cui punta this.sender in quel momento, non a cosa indica quando hai creato la chiusura.

È possibile evitare questo problema creando il proprio locale, copia immutabile il contenuto corrente della this.sender, e riferimento tale valore nella chiusura:

val origSender = sender 
f.onComplete { 
    case Successs(x) => origSender ! x 
    ... 
} 
+0

è necessario anche per 'self'? –

+1

@GeorgePligor No, self non è mutabile. – stew

4
import akka.pattern.pipe 

Il trucco. Fare:

val reply = sender 
future { 
    val ans = searchAndCache(s) 
    println("Input Request: "+s+" output:"+ans+" "+reply.path) 
    ans 
} pipeTo reply 

risponde al mittente

+8

Sembra che questa risposta si focalizzi in modo errato o fuorviante su pipeTo. Per quanto ne so, usando pipeTo al posto di! non ha risolto il problema Salvare il mittente in "risposta" è ciò che impedirebbe il comportamento che stavate vedendo prima, che è la risposta su cui si concentra la risposta dello stufato. – mushroom

Problemi correlati