2014-04-02 64 views
1

我在scala中使用Play框架。我是斯卡拉,阿卡和玩的新手。鏈接Akka Actor詢問呼叫的正確方法是什麼?

這是我的演員系統。我不確定我是否做得對,但我有兩臺路由器。 1男演員A,和1對演員B:

val system = ActorSystem("ActionSystem") 
    val actorARouter = system.actorOf(Props[ActionParser].withRouter(
    SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorARouter") 
    val actorBRouter = system.actorOf(Props[ActionDispatcher].withRouter(
    SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorBRouter") 

這是當前的設置,我有: 該劇框架提供了我,收到了一些JSON一個HTTP REST調用的控制器。每當控制器接收一個REST調用,我做了一個請發送JSON爲演員A.這裏路由器是什麼樣子:

(actorARouter ? request.body.asJson.get).map { 
     case m: controllers.HttpMessages.OK => Ok(m.body) 
     case m: controllers.HttpMessages.HttpResponse => Status(m.status)(m.body) 
    } 

演員A然後解析成JSON對象的序列,然後發送他們通過詢問演員B.演員B應該最終通過發送給其他演員來處理這些演員,但現在只是返回通用響應。

ActorA通過未來接收到通用響應,然後解析爲JSON,然後通過OK響應返回給Controller ...或者至少這是應該發生的事情。

發生了什麼事: 所以發生了什麼事是控制器發送到ActorA,ActorA發送到ActorB。 ActorB向ActorA發送通用響應。 ActorA將通用響應解析爲JSON,並嘗試執行sender ! OK(json),但我在控制檯中收到一條消息,稱它並未傳遞,因爲它是「死信」。當我調試到它時,我看發件人,發件人是對演員的參考akka://ActionSystem/deadLetters

我的問題:

  1. 很顯然,我做錯了什麼。也許我不應該像這樣一起鏈接這些演員的反應。我再次提到,我只有計劃通過讓ActorB向其他演員發送請求來進一步提高這一點。
  2. 當我在一個演員中問一個問題時,那不會妨礙那個線程,並在等待響應時阻止它處理其他消息嗎?

編輯: 我發現我可以保存到發件人供以後使用的參考,然後發送到,這似乎解決了一紙空文問題。但我仍然很不確定這是否是正確的做法。感覺就像每次添加另一層演員時,我的響應時間都會添加10毫秒的毫秒數。也許這是由於其他因素。

回答

3

沒有看你的代碼,我不能真正評論是什麼導致了死信,從你的編輯我猜你關閉了sender()而不是分配給一個變量,並結束了。

要回復您的問題:

  1. 這是很容易構造消息流的演員,如果你只使用發射後不管的消息。 ask模式在某些情況下很有用,但大多數情況下您應該儘量避免使用它。你可以做的是通過使用forward而不是tell來讓原始發件人通過你的演員。通過這種方式,消息流中的最後一個角色可以生成響應。第一個參與者只需要代碼來處理響應,而不需要關心生成響應。好的問題分離就在那裏。如果您需要彙總幾個響應以便之後發送單個響應,您還可以使用臨時演員,讓所有其他演員將響應發送給該演員,並知道該原始發件人。臨時演員在完成工作後需要停下來。
  2. 就我所知問題模式是異步的,並在內部使用臨時參與者。但是,如果您在演員中等待未來的結果,則會阻止該演員,並且無法處理更多消息。使用ask模式的一個不錯的方法是與pipeTo模式結合使用,您可以使用它將問題結果發送給演員(通常爲self
+1

感謝您的回覆。基本上,當我最終得到對ActorA的響應時,發件人指向地址「akka:// ActionSystem/deadLetters」。在我提出問題之前,我可以通過執行val savedSender = sender來解決此問題,並對savedSender進行響應。 – spierce7

相關問題