2013-06-03 45 views
15

我有一個演員一旦收到消息,搜索文件系統的文件,並返回文件的完整路徑。發件人內未來

要保持它的異步,我已經做了:

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

} 

但我觀察到,該消息返回給akka://FileSystem/deadLetters而不是sender。文檔說明:

只限於演員本身,所以不要關閉它和 *發佈給其他主題!

那麼這是不是意味着,我將不得不保持同步?有沒有其他方法?

+0

爲什麼要使用一個未來?這是一個I/O操作(等可能阻塞),這樣就把演員在阻擋-IO調度。如果您需要一次搜索多個文件,有多個實例運行。 –

回答

32

您正在「關閉了可變狀態」的一個非常常見的錯誤。你傳遞給onComplete的封閉不會使副本this.sender,所以當你的onComplete被調用,您要發送到任何this.sender發生在那個時候指向,不是它指出,在創建關閉的消息。

您可以避免通過創建的this.sender當前內容自己本地的,一成不變的副本這個問題,並說明在截流值:

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

這是'self'的必要嗎? –

+1

@GeorgePligor沒有,自不可變。 – stew

4
import akka.pattern.pipe 

是否有竅門。這樣做的:

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

回覆給發件人

+8

好像這個答案不正確或誤導性的重點pipeTo。據我所知,使用pipeTo而不是!沒有解決問題。保存發件人在「回覆」是什麼會阻止你之前看到的行爲,這是燉的回答集中在。 – mushroom