20

メッセージを受信すると、ファイルシステムでファイルを検索し、ファイルのフルパスを返すアクターがあります。

非同期に保つために、次のことを行いました。

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。ドキュメンテーションは次のように述べています。

アクター内でのみ有効なので、アクターを閉じて * 他のスレッドに公開しないでください!

つまり、必然的に同期を維持する必要があるということですか? 他に方法はありますか?

4

3 に答える 3

46

「可変状態を閉じる」という非常に一般的な間違いを犯しています。渡したクロージャーはonCompleteのコピーを作成しないため、this.senderが呼び出されると、クロージャーを作成したときに指していたものではなく、その時点でたまたま指していたものにonCompleteメッセージを送信します。this.sender

this.senderの現在のコンテンツの独自のローカルで不変のコピーを作成し、クロージャでその値を参照することで、この問題を回避できます。

val origSender = sender
f.onComplete {
    case Successs(x) => origSender ! x
    ...
}
于 2013-06-03T13:52:22.787 に答える
3
import akka.pattern.pipe

トリックを行います。やっている:

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

差出人に返信する

于 2013-06-03T13:44:23.590 に答える