Scala向自己发送消息好还是坏?

时间:2014-11-05 17:06:53

标签: scala asynchronous playframework akka actor

我在播放框架中使用了json4s,并且我将来会在某些地方运行发布/获取请求,然后onSuccess将响应解析为一个对象并让演员将其发回对自己来说..这是一个例子:

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

然后返回接收方法:

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

这是不好的做法吗?有什么正确的方法可以解决这个问题?我看到的优势是能够让你的演员数据流由单一的控制结构处理,但当然我说这是一个优势是错误的。

2 个答案:

答案 0 :(得分: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),而不是结果。

将未来的结果管道化为self是一种常见的模式,可能与context.become / unbecome和stash一起使用以创建状态机。

在map / flatmap中关闭actor内部可变状态并且在执行此操作时打破actor模型的并发保证仍然非常容易。如果你在演员中操纵未来我强烈建议你阅读这个http://doc.akka.io/docs/akka/2.3.2/general/jmm.html#jmm-shared-state,如果你还没有这样做的话。

答案 1 :(得分:1)

它没有任何内在错误。向自己发送消息类似于人类保持"做"列出并将一些内容放在列表的末尾。你的演员最终会到达那里。并且,这确实是唯一的问题:何时处理AuthObject消息的时间。如果您的应用程序只需要订购但不需要时间保证,那么可以这样处理它。

但是,我会警惕你的\运算符在没有" body"的情况下返回JsError。你的response.body中的字段(大概是Json)。在这种情况下,您的消息永远不会被发送,并且在任何地方都没有发送任何错误。