2016-07-25 9 views
1

俳優の内側に未来から「送信者」に戻って -私はこのような何かやりたい

class MyActor extends Actor { 
.... 
override def receive = { 
    case msg => 
    .... // do something 
    Future { 
     ... // calculate response 
     sender ! response 
    } 
} 
} 

// in some other code - 
val future = myActorRef ? msg 
future.onSuccess { 
    .... 
} 

うこの仕事を?つまり、「受信」メソッドが終了する前に応答が返された場合、Akkaの「尋ねる」実装は注意を払いますか?

答えて

5

はい、それはうまくいく、とさえそこにビルトインされたことについてアッカパターン - pipe

import akka.pattern.pipe 

override def receive = { 
    case msg => 
    .... // do something 
    Future { 
     ... // calculate response 
     response 
    } pipeTo sender() 
} 

あなたは注意する必要があり、あなたのコード内しかし、いくつかの注意点があります:

senderですしたがって、あなたのFuture{...}ブロック内のコードが実行されるとき、アクターは別の送信者からのメッセージを処理している可能性があります。そのため、間違った送信者に返信することができます。これを避けるために、クロージャの外にあなたの送信者を評価:

val mySender = sender() 
Future { 
    ... // calculate response 
    mySender ! response 
} 

ただし、あなたがpipeを使用する場合は、このことを心配する必要はありません。


あなたが俳優に未来をラップして、もう一度あなたに未来を与えるask、とその俳優を呼んでいます。あなたは実際に俳優なしで、未来を直接呼び出すことを検討すべきです。 実際に俳優が必要な場合、たとえばあなたが変更可能な状態やメッセージの順序付けを分離しているので、Futureの計算は俳優のスレッドでは起こりませんので、状態の一貫性とメッセージの順序が失われていることに気づかなければなりません。未来を直接呼びます。

+0

通常、私は俳優(ここでは俳優がほとんど何もしません)の中で未来に行くことはありません。しかし私の場合、私は俳優だけにメッセージを送ることができる別の図書館に依存しています。したがって、質問:-) – anindyaju99

1

将来問題が発生すると、senderは無効になることがあります。

あなたはキャプチャ未来前senderができます::

override def receive = { 
    case msg => 
    .... // do something 
    val replyTo = sender 

    Future { 
     ... // calculate response 
     replyTo ! response 
    } 
} 

それとも、pipeToパターンを使用することができますが、ここで、オプションのカップルを持っている私の頭の上から2つです

override def receive = { 
    case msg => 
    .... // do something 
    import akka.pattern.pipe 

    Future { 
     ... // calculate response 
    }.pipeTo(sender()) 
} 
関連する問題