2017-08-16 6 views
0

チェーン条件付き俳優今、俳優A型Try[AbcResponse]の応答を返します。 AbcResponseはここのケースクラスです。いくつかのロジックに基づいて 俳優Aは、直接このレスポンスを返すことがありますか、それは条件付きで頼む使用して別のアクターBを呼ぶかもしれません。 Bからの応答を操作した後、それがコントローラにタイプTry[AbcResponse]の応答を送信することになります。はスカラ:私はAとB Aコントローラは俳優Aにリクエストを送信する2人の俳優を持って

だから私はこのような状況に対処するために、私の俳優Aに何をすべきか。私は、スレッドプールを無駄にし、システムの減速を引き起こすので、私の俳優Aに待っているのを望んでいません。どのように私はこれを効率的に処理できますか?

答えて

0

アクターBへのメッセージで送信者参照を渡し、pipeアクターBからの応答をselfに渡すことができます。上記のアプローチは安全ですが、明らかにその応答で俳優のBはバック俳優Aに

import akka.pattern.{ask, pipe} 

case class MsgToActorB(..., target: ActorRef) 
case class ResponseFromActorB(..., target: ActorRef) 

class ActorA extends Actor { 
    def receive = { 
    case r: Request => 
     val s = sender 
     implicit val timeout = Timeout(5 seconds) 
     // do something with the request 
     if (someCondition) 
     s ! Try(AbcResponse(...)) 
     else 
     (actorB ? MsgToActorB(..., s)).mapTo[ResponseFromActorB].pipeTo(self) 

    case ResponseFromActorB(..., target) => 
     // do something with the response from B and send a response to the original sender 
     target ! Try(AbcResponse(...)) 
    } 
} 

をこの参照を渡す必要があり、以下に示すようにaskを使用しない方が簡単だろう。あなたはaskを使用して、それが俳優のAからのメッセージを処理する際の俳優Bがブロックしている場合は、説明hereとして別々のディスパッチャを設定することを検討する必要がある場合。

def receive = { 
    case r: Request => 
    val s = sender 
    // do something with the request 
    if (someCondition) 
     s ! Try(AbcResponse(...)) 
    else 
     actorB ! MsgToActorB(..., s) 

    case ResponseFromActorB(..., target) => 
    // do something with the response from B and send a response to the original sender 
    target ! Try(AbcResponse(...)) 
} 
+0

この状況では、アクターBを呼び出すと、アクター自体にコールバックを入れるのは悪いですか? – Sidhant

+0

@Sidhant:[ここ](http://doc.akka.io/docs/akka/2.5.4述べたようask' 'と'(コールバックはない)mapTo'と 'pipeTo'を使用して、一般的なパターンであります/scala/actors.html#ask-send-and-receive-future)およびドキュメントの他の部分に記載されています。 – chunjef

関連する問題