如何从尚未准备好的其他演员那里请求数据?

时间:2018-11-08 18:30:32

标签: scala akka

我有一个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
      }
  }
}

在发送方演员中,我使用询问模式:

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

在数据提供者参与者中,它将数据发送到参与者A:

dataActor ! 100

问题在于,当请求者请求数据时,数据可能尚未准备就绪,因此,来自请求的Future可能会失败。我需要向发送方发送一些东西以保证有数据,但是显然Akka似乎没有保证AKAIK。

如何在这里实现?

1 个答案:

答案 0 :(得分:0)

两种可能性。

首先,您可以返回实际的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
 }