2014-11-05 56 views
4

我正在使用json4s和play framework,我有一些地方我會在將來運行post/get請求,然後onSuccess將響應解析爲一個對象並讓actor將它發回給自己。一個例子:斯卡拉發送消息給自己好還是壞?

WS.url(authUrl).post("username=admin&password=admin") map { 
    response => 
    self ! (parse(response.body) \ "body").extract[AuthObject] 
} 

,然後在接收方法回:

case AuthObject(_, sid) => //handle authorization token 

這是不好的做法?什麼是正確的方式去做這件事?我看到的優勢是能夠讓演員的數據流由單個控制結構來處理,但當然,我認爲這是一個優勢,可能是錯誤的。

+2

如果在演員內部有一個Future,並且該演員的狀態需要在未來完成後更新,那麼唯一安全的方法是將消息發送回自己,以便返回上下文的演員。在正確的情況下,這是一種有用的做法。 – cmbaxter 2014-11-05 18:50:50

+1

所以你說這是這種情況的最佳做法?這很讓人放心,謝謝! – JBarber 2014-11-05 19:38:45

+1

修復idotic tagging'play framework'與'playback'無關 – biesior 2014-11-06 20:49:08

回答

8

recommended向演員發送未來結果的方法是使用pipe模式。然後,您的代碼應該是這樣的:

def receive:Reveice= { 
    case authUrl:String => 
    val authObjectF=WS.url(authUrl).post("username=admin&password=admin") map { response => 
     (parse(response.body) \ "body").extract[AuthObject] 
    } 
    authObjectF pipeTo self 
} 

這被認爲優於map {x => self ! x }的原因是錯誤處理。如果你不處理這些錯誤情況,他們將被簡單地丟棄。 使用pipe模式,錯誤將被包裝在akka.actor.Status.Failure中,併發送到目標參與者(在本例中爲self)以代替結果。

將未來的結果管理到自我是一種常見模式,可能與context.become/unbecome一起使用並存儲以創建狀態機。

在地圖/平面地圖中關閉actor內部可變狀態仍然非常容易,並且這樣做會破壞actor模型的併發性保證。如果你正在操縱演員的未來,我強烈建議你閱讀這個http://doc.akka.io/docs/akka/2.3.2/general/jmm.html#jmm-shared-state,如果你還沒有這樣做。

1

它沒有什麼內在的錯誤。向自己發送消息與保持「待辦事項」列表並將某些內容放在列表末尾的人類似。你的演員最終會到達那裏。而且,這真的是唯一的問題:處理AuthObject消息的時間。如果您的應用程序只需要訂購,但沒有時間保證,那麼以這種方式處理就可以了。

然而,如果你的response.body(大概是Json)沒有「body」字段,那麼你的\運算符返回一個JsError。在這種情況下,你的消息永遠不會被髮送,而且任何地方也不會有錯誤發送。