Sou*_*nta 7 scala future actor akka
我正在创建一群做一些工作的演员,然后他们就被制止了.在其中一些演员中,我正在调用返回的第三方API Future.
MyActor extends Actor
{
....
def receive = {
case MsgA => {
...
//this evaluates to a Future
val p : Future = someFutureAPICall()
//stop the actor
context stop self
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,由于Future是非阻塞的演员会之后已停止(?),即使Future还没有完成.在这种情况下,预期的行为是什么?
举例来说,如果我有一onComplete对Future,将是有史以来被即使演员已停止执行?
MyActor extends Actor
{
....
def receive = {
case MsgA => {
...
//this evaluates to a Future
val p : Future = someFutureAPICall()
p.onComplete {
//will these expressions ever be evaluated ?
case Success(x) => log.info("Success")
case Failure(f) => log.info("Failure")
}
//stop the actor
context stop self
}
}
}
Run Code Online (Sandbox Code Playgroud)
是的,返回Future(第三方API)的代码将立即执行并返回不完整的Future.
完成这个未来的执行与开始活着的演员无关.
如果您不再需要该演员,则无需等待Future完成,您可以像第一个示例中那样停止演员.
如果您需要在该actor中执行具有该未来结果的操作,则可以onComplete在该Future上安装回调.一旦Future完成,它可以向演员发送消息以停止.例如这样:
val myActor = self // Don't close over unstable actor reference by using self directly
p.onComplete {
case Success(x) => myActor ! x; myActor ! akka.actor.PoisonPill // sends result to be processed and then stops actor
case Failure(f) => myActor ! akka.actor.PoisonPill // stops actor
}
Run Code Online (Sandbox Code Playgroud)
编辑
注释中建议的另一种替代方法是使用pipeTo使用模式.它几乎完全相同.以下是它在Akka库中的实现方式:
def pipeTo(recipient: ActorRef)(implicit sender: ActorRef = Actor.noSender): Future[T] = {
future onComplete {
case Success(r) ? recipient ! r
case Failure(f) ? recipient ! Status.Failure(f)
}
future
}
Run Code Online (Sandbox Code Playgroud)
以下是在创建Future之后可以调用它的方法:
p pipeTo myActor
Run Code Online (Sandbox Code Playgroud)
您的演员在接收消息后必须关闭自己的主要区别,并且失败显然会通过Failure消息传达给演员.使用此方法更安全,因为您必须传递一个,ActorRef而不必记住将其(自身)复制到变量中.
| 归档时间: |
|
| 查看次数: |
2006 次 |
| 最近记录: |