Почему я не получаю исключение времени ожидания Ask? - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть 2 актера, один руководитель и ребенок.

Руководитель:

class DemoActorSupervisor(implicit val system: ActorSystem, config: Config) extends Actor {

  val childActor: ActorRef = context.actorOf(FromConfig.props(Props[DemoActorChild]), "DemoChildActor")

  context.watch(childActor)

  override def receive: Receive = {
    case s: String =>
      childActor forward s
  }
}

Детский актер:

class DemoActorChild extends Actor {
  def receive: Receive = {
    case s: String =>
      Thread.sleep(100)
      Future.successful(true) pipeTo (sender)
  }
}

Основной метод:

object ABC extends App {
  implicit val system: ActorSystem = ActorSystem("Demo")

  implicit val config: Config = ConfigFactory.load()

  implicit val timeout: Timeout = Timeout(5, TimeUnit.MILLISECONDS)

  val supervisor = system.actorOf(DemoActorSupervisor.props(), "DemoSupervisor")

  val x: Future[Boolean] = (supervisor ? ("ASK")).mapTo[Boolean]
  x.foreach(println)
}

Я установил тайм-аут запроса на 5 миль и выполняю вызов с запросом к наблюдателю. который пересылает сообщение дочернему актеру. В роли актера-ребенка я логически поставил Thread.sleep(100). Я должен получить исключение времени ожидания запроса, поскольку я установил тайм-аут на 5 миллисекунд, а ребенку требуется более 100 милисекунд, чтобы ответить, но я не получаю исключения для тайм-аута запроса. может кто-нибудь сказать мне, что не так с кодом? Как я могу получить исключение тайм-аута.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Вы можете увидеть в описании Future.foreach:

Асинхронно обрабатывает значение в будущем, как только оно станет доступным.

ПРЕДУПРЕЖДЕНИЕ: не будет вызвано, если это будущее никогда не завершается или если оно завершается с ошибкой.

Если вы хотите использовать Future.foreach, вы должны написать что-то вроде:

x.map(Success(_)).recover({case exception => Failure(exception)}).foreach(println) 
0 голосов
/ 04 сентября 2018

Попробуйте следующее:

x.onComplete {
    case Success(v) =>
      println(v)
    case Failure(v) =>
      println(v)
}

Future foreach просто обработайте случай успеха, akka.pattern.AskTimeoutException: принадлежит Failure, вам нужно обработать его своим кодом.

Или следующее тоже нормально:

x.foreach(println)
x.failed.foreach(println)
...