演员模型中futures的执行上下文

7

我有一个Actor,在某些消息上运行一些方法,该方法返回Future。

 def receive: Receive = {

    case SimpleMessge() =>
        val futData:Future[Int] = ...
        futData.map { data =>
           ... 
        }
}

在等待这个数据时是否可以传递实际上下文?或者在SimpleMessage中需要这个数据时,Await是最好的选择吗?


你想使用来自Future的数据做什么? - cmbaxter
这些是来自我的数据库(mongo)的数据,我想要对它们进行过滤,并且只保存其中的一部分到另一个集合中。但基本上这些都是数据库数据,我不能在后台运行它们,必须等待此操作完成后才能进行下一个SimpleMessage - Michał Jurczuk
它是否会向“发送者”发送消息? - Michael Zajac
不,无需等待响应。 - Michał Jurczuk
1个回答

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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接