我有一个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。
如何在这里实现?
答案 0 :(得分:0)
两种可能性。
首先,您可以返回实际的Option
(data.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
}