【问题标题】:Execution context for futures in ActorsActor 中期货的执行上下文
【发布时间】:2014-08-04 06:13:22
【问题描述】:

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

 def receive: Receive = {

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

是否可以传递实际上下文来等待此数据?如果我需要 SimpleMessage 中的这些数据,或者Await 是我能做的最好的吗?

【问题讨论】:

  • 您究竟希望如何处理来自 Future 的数据?
  • 这是来自我的数据库(mongo)的数据,我想过滤它们,只有一部分保存到另一个集合中。但基本上这是数据库数据,我不能在后台运行它,我必须等待在下一个 SimpleMessage 之前完成这个动作。
  • 是发回消息给sender还是没有?
  • 不,不等待响应

标签: scala akka actor future


【解决方案1】:

如果您确实需要等待未来完成才能处理下一条消息,您可以尝试以下操作:

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,然后切换处理逻辑以存储所有后续收到的SimpleMessages,直到我们从未来获得结果。当我们得到结果时,无论是否失败,我们都会取消隐藏在等待未来时收到的所有其他 SimpleMessages,然后继续我们的快乐之路。

这个actor只是在两种状态之间来回切换,这使您一次只能完全处理一个SimpleMessage,而无需阻塞Future。

【讨论】:

    猜你喜欢
    • 2013-05-12
    • 2016-02-16
    • 2018-08-04
    • 2015-03-10
    • 2017-07-09
    • 2016-07-11
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    相关资源
    最近更新 更多