remitente dentro de un futuro

Tengo un actor que al recibir un mensaje, busca en el sistema de archivos un archivo y devuelve la ruta completa del archivo.

Para mantenerlo asincrónico, lo he hecho:

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") } } } 

Pero he observado que devuelve el mensaje a akka://FileSystem/deadLetters y no al sender . La documentación dice que:

Solo es válido dentro del Actor, así que no lo cierres y * ¡publícalo en otros hilos!

Entonces, ¿significa que tendré necesariamente que mantenerlo sincrónico? ¿Hay alguna otra manera?

Está cometiendo un error muy común de “cerrar el estado mutable”. El cierre que pasa a onComplete no hace una copia de este this.sender , por lo que cuando se llama a su onComplete , está enviando el mensaje a lo que sea que this.sender ocurra. El this.sender señala en ese momento, no lo que señaló cuando creó el cierre.

Puede evitar este problema creando su propia copia local e inmutable de los contenidos actuales de this.sender y hacer referencia a ese valor en el cierre:

 val origSender = sender f.onComplete { case Successs(x) => origSender ! x ... } 
 import akka.pattern.pipe 

Hace el truco. Obra:

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

responde de nuevo al remitente

Sé que esto es viejo, pero tengo que agregar esto,
el pipeTo es el camino correcto, pero no necesita copiar su remitente ,
ya estás en el mismo contexto.
En realidad, el pipeTo hace esto por ti.
tomará el remitente actual ref (pasando a su argumento)
y úsala para resolver el futuro para ti (mira su implementación)
solo haz:

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