首页 > 解决方案 > 如何向另一个还没有准备好的参与者请求数据?

问题描述

我有一个actorA,它从dataActor 获取数据,并将数据响应到requestActors:

class A extends Actor {
  var data = Option.empty[Int]
  val requestors = mutable.Set[ActorRef]

  def receive = {
    case data: Int => 
      this.data = Some(data)
      requestors.foreach {_ ! data}
    case Request => 
      if (data.isEmpty) {
        requestors.add(sender)
        //What should I send back to sender here?
      } else {
        sender ! data.get
      }
  }
}

在发送方actor中,我使用了询问模式:

(actorA ? Request()).map {
  //if the data is not ready here, how can I wait for data?
}

在数据提供者actor中,它将数据发送给actorA:

dataActor ! 100

问题是当请求者请求数据时数据可能还没有准备好,因此请求的 Future 可能会失败。我需要向发件人发送一些东西以保证有数据,但显然 Akka 似乎没有承诺 AKAIK。

如何在这里实现?

标签: scalaakka

解决方案


几种可能性。

首先,您可以返回实际的Optiondata.get无论如何都是“代码气味”,最好避免):

 case Request() => data

然后继续在客户端尝试:

 def result: Future[Int] = (actor ? Request()).map { 
    case Some(n) => n
    case None => after(1 second, system.scheduler)(result)
 }

或者,返回一个Future

val ready = Promise[Int]()

case data: Int => 
   this.data = data
   ready.complete(data)
case Request() => 
   data.fold(ready.future)(Future.successful)

现在,您只需在调用方将其展平:

 val result: Future[Int] = (actor ? Request()).flatMap {
    case f: Future[Int] => f
 }

推荐阅读