2014-11-05 59 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。在这种情况下,你的消息永远不会被发送,而且任何地方也不会有错误发送。