2013-05-20 141 views
11

您是否知道在Akka/Scala中添加/刪除路由到Broadcaster路由器的好方法?動態添加/刪除路由到路由器角色

我一直在尋找調整器 - 但不符合我的需求(我看不出如何明確要求調整大小來調整大小(添加路線)並刪除它似乎你需要發送一個毒丸給演員然後被刪除)。

到目前爲止,我有ActorRef列表的路由器,我送AddRoutee和RemoveRoutee消息....

我的商業案例:我有一個演員從網絡獲取數據(通過代理),並且它需要將這些數據分發給獨立的參與者並行處理。由於收件人(DAG)的圖形性質,圖形可以在運行時演變,頂點/邊緣被修改,因此需要添加和刪除路徑。

必須有一種更簡潔的方式來完成此操作。

感謝您的指點。

的代碼示例,我想阿卡處理:

class MDActor extends Actor { 
    @volatile var routees = Set[ActorRef]() 

    def receive = { 
    case ar: AddRoutee => routees = routees + ar.actorRef 
    case rr: RemoveRoutee => routees = routees - rr.actorRef 
    case msg => routees.foreach(r => r forward msg) 
    } 
} 
+0

您能否提供一些更多的背景知道您的代碼中發生什麼情況會導致從路由器添加/刪除路由?這種信息將有助於提出解決方案。 – cmbaxter

+1

在你的例子中,我建議使用Set [ActorRef]而不是List [ActorRef]來防止路由重複。並使用「前進」而不是「!」保留原始發件人。 –

+0

謝謝。這是一個好主意。 – jts

回答

2

每當您發現自己在路由器中缺少某項功能時,現在是開始思考另一個方向的好時機:您提供的演員代碼出了什麼問題?除非你需要每秒發送超過幾百萬條消息(這在描述時不太可能),這樣的演員恰恰是正確的解決方案。路由器是一個非常專業化的結構,不應該被用作替代品;只有在他們完全符合你的要求時才使用它們,並且你有一個普通演員不足以達到的基準。

+0

羅蘭,我的用例非常具體..甚至對於「java」。所以上面的模式適用於我想要的代碼。的確,我可以用Java的方式來完成它......那有什麼樂趣? – jts

+0

我不明白這個評論,因爲我沒有在我的答案中談論Java。我的答案歸結爲「你知道了,停止尋找」;-) –

+0

沒有。一直在尋找是否有更好的方式來做東西:-) – jts

1

不知道真的是有一個更好的辦法,而不是保持狀態有關routees並建立在每一個變化的新路由器或者不使用路由器,並使用普通的演員。我最近也看了這個。

恩惠不變 - 那麼最有利的解決方案很可能是扔掉舊的路由器和/或集合,並建立一個新的路由器或集合/演員地圖。

你可以跟蹤你的演員而不使用路由器 - 這是一個很好的解決方案,並且在akka文檔中推薦作爲路由器的一個簡單替代方案。路由器應該比完整的演員具有性能優勢。

您可以在此處演示如何構建具有參與者列表的路由器。 每次有變化時都要這樣做。 (來源:阿卡文檔 - http://doc.akka.io/docs/akka/snapshot/scala/routing.html

val actor1 = system.actorOf(Props[ExampleActor1]) 
val actor2 = system.actorOf(Props[ExampleActor1]) 
val actor3 = system.actorOf(Props[ExampleActor1]) 
val routees = Vector[ActorRef](actor1, actor2, actor3) 
val router2 = system.actorOf(Props().withRouter(
    RoundRobinRouter(routees = routees))) 

這裏顯示了ROUNDROBIN路由器但是這並不比使用廣播一個什麼不同。

重新創建這個功能有點多。

+0

這實際上工作嗎?實例化路由器時出現錯誤。 – mbseid

+0

好吧,請確保它符合您使用的AKK版本:)另請注意,唯一的一個Roland Kuhn回答:)我們確實重新創建了在構建編排/通信庫時隨機發送給我們的演員參考數組。重新創建路由器也是可行的。 – JasonG

+0

Gotcha。我更關注上述聲明的實際編制。我不得不使用Props.empty。它可能是一個版本的東西。 – mbseid