簡體   English   中英

Akka Pattern - 演員樹,回復原始來源

[英]Akka Pattern - Actor tree, reply to original source

這是一個設計問題;

假設我有一組演員,他們會做一堆處理。 處理由客戶端/連接參與者啟動(即樹是服務器)。 最終客戶端演員想要一個響應。 即我有一個看起來像這樣的演員系統。

    ActorA  <---reqData--- Client_Actor
       | msgA                    /|\                      
      \|/                         |                 
    ActorB                        |                  
  msgB |  \ msgD                  | 
      \|/  \/                     | 
    ActorC  ActorD---------msgY-->|
       |_____________msgX_________|

客戶端系統想要的響應是葉子actor(即ActorC和/或ActorD )的輸出。 樹中的這些參與者可能正在與外部系統進行交互。 該樹可以是一組預定義的可能路由的actor(即,因此Client_actor只有一個actorref到actor樹的根, ActorA )。

問題是管理從最終/葉子演員返回到客戶端演員的響應( msgX和/或msgY )的最佳模式是什么?

我可以想到以下幾種選擇;

  • 為每個連接客戶端創建一個樹,並讓演員跟蹤發件人,當他們獲得msgXmsgY ,將其發送回原始發件人引用,以便將消息傳遞回樹中。 即每個演員都會保留原始發件人的參考號。
  • 以某種方式向下發送reqData消息中的Client_Actor引用並為樹中使用的所有消息復制它,以便葉子actor可以直接回復到Client_actor ......這似乎是最高性能的選項。 不知道如何做到這一點(我在某種方式上考慮了包含客戶端參與者的消息案例類的特征)...
  • 以某種方式根據通過樹傳遞的消息中的唯一ID查找客戶端actor或使用actorselection(不確定這對遠程處理有多好)...
  • 更好的東西...

僅供參考我正在使用Akka 2.2.1。

干杯!

您可以使用forward方法將郵件從原始發件人轉發到每個級別的子發件人。

在Client_Actor中:

actorA ! "hello"

在ActorA中:

def receive = {
  case msg =>
    ???
    actorB forward msg
}

在ActorB中:

def receive = {
  case msg =>
    ???
    actorC forward msg
}

在ActorC中:

def receive = {
  case msg =>
    ???
    sender ! "reply" // sender is Client_Actor!
}

在這種情況下,消息的“發送者”字段永遠不會改變,因此ActorC將回復原始的Client_Actor!

您可以使用tell方法變體進一步擴展它,該變量允許您指定發送方:

destinationActor.tell("my message", someSenderActor);

最簡單的方法是將帶有ref的消息發送到源Client_Actor

Client
 sendMsg(Client to, Client resultTo)

Client_Actor
 req_data(Client to){
   sendMsg(to, this);
 }

這是一個不錯的選擇,如果你不知道,哪個客戶有原始海報的結果,哪個不是。

如果您知道這一點並且Client_Actor只有一個(就像我們有一個樹而且這些只有LEAFS將始終響應並且只響應Client_Actor),您可以執行以下操作:

Client
  register_actor(Client actor){this.actor = actor;}
  call_actor(){ this.actor.sendMsg(); }

對於這樣的情況,我寫了一個名為ResponseAggregator東西。 它是一個根據需要實例化的Actor (而不是作為持久性單個實例)將目標ActorRef作為參數,一個任意key (如果單個目標由多個聚合器提供,則區分聚合器),一個完成謂詞Seq[Any]保持聚合器到目前為止收到的響應,如果這些響應表示聚合過程完成和超時值,則返回true 聚合器接受並收集傳入消息,直到謂詞返回true或超時到期。 一旦聚合完成(包括由於超時),所有已接收的消息將與指示聚合是否超時的標志一起發送到目的地。

代碼有點太大,不能包含在這里,不是開源的。

為此,傳播通過系統的消息必須帶有ActorRef指示響應消息將被發送給誰(我很少設計只回復sender者的actor)。

我經常將消息值的replyTo字段定義為ActorRef* ,然后使用我的MulticastActor類,它啟用!* “發送給多個收件人”運算符。 這具有消息構造中語法清潔的優點(通過與使用Option [ActorRef]或Seq [ActorRef]相比)並具有相同的開銷(需要構造一些東西來捕獲回復的actor ref或refs)。

無論如何,通過這些功能,您可以設置非常靈活的路由拓撲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM