我有一个Actor,在某些消息上我正在运行一些返回Future的方法。
def receive: Receive = {
case SimpleMessge() =>
val futData:Future[Int] = ...
futData.map { data =>
...
}
}
是否可以通过实际上下文来等待这些数据?或者Await
是我在 SimpleMessage 中需要这些数据时能做的最好的事情吗?
答案 0 :(得分:10)
如果你真的需要在处理下一条消息之前等待将来完成,你可以试试这样的事情:
object SimpleMessageHandler{
case class SimpleMessage()
case class FinishSimpleMessage(i:Int)
}
class SimpleMessageHandler extends Actor with Stash{
import SimpleMessageHandler._
import context._
import akka.pattern.pipe
def receive = waitingForMessage
def waitingForMessage: Receive = {
case SimpleMessage() =>
val futData:Future[Int] = ...
futData.map(FinishSimpleMessage(_)) pipeTo self
context.become(waitingToFinish(sender))
}
def waitingToFinish(originalSender:ActorRef):Receive = {
case SimpleMessage() => stash()
case FinishSimpleMessage(i) =>
//Do whatever you need to do to finish here
...
unstashAll()
context.become(waitingForMessage)
case Status.Failure(ex) =>
//log error here
unstashAll()
context.become(waitingForMessage)
}
}
在这种方法中,我们处理SimpleMessage
,然后切换处理逻辑以存储所有后续的SimpleMessage
,直到我们从未来获得结果。当我们得到一个结果,无论是否失败,我们会在等待未来的同时解除我们收到的所有其他SimpleMessage
,并继续我们的快乐方式。
这个actor只是在两个状态之间来回切换,允许你一次只完全处理一个SimpleMessage
而不需要阻止Future。