2013-06-03 11 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操作です(ブロックする可能性もあります)ので、アクターをblocking-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

関連する問題