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

JBa*_*ber 4 asynchronous scala actor akka playframework

我正在使用json4s和play框架,我有一些地方可以在将来运行post/get请求,然后onSuccess将响应解析为一个对象并让actor将它发送回自身..这是一个例子:

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

然后回到receive方法:

case AuthObject(_, sid) => //handle authorization token
Run Code Online (Sandbox Code Playgroud)

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

Jea*_*ean 8

将未来结果发送给actor 的推荐方法是使用该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
}
Run Code Online (Sandbox Code Playgroud)

这被认为优于map {x => self ! x }错误处理的原因.如果您不处理错误情况,它们将被默默地丢弃.使用该pipe模式,错误将被包装在a中akka.actor.Status.Failure并发送到目标actor(在本例中为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,如果你还没有这样做的话.