Как запросить данные у другого актера, который еще не готов? - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть 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 from ask может потерпеть неудачу. Мне нужно отправить отправителю что-то, чтобы пообещать, что есть данные, но, видимо, Акка, похоже, не обещает AKAIK.

Как это реализовать здесь?

1 Ответ

0 голосов
/ 09 ноября 2018

Пара возможностей.

Во-первых, вы можете вернуть действительное значение Option (data.get в любом случае является «запахом кода», и его лучше избегать):

 case Request() => data

А затем просто продолжайте примерять клиентаend:

 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
 }
...