Raman Mishra
Raman Mishra

Reputation: 2686

Why i'm not getting Ask timeout exception?

I have 2 actors one supervisor and a child actor.

The supervisor:

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

Child actor:

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

Main method:

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

I have set the ask timeout as 5 mili seconds, and doing an ask call to the supervisor actor. which is forwarding the message to the child actor. In the child actor I have put Thread.sleep(100) logically I should get the ask timeout exception as I have set timeout to 5 mili seconds and child is taking more than 100 mili second to respond back, but I am not getting ask timeout exception. can someone tell me what's wrong with the code? How can I get ask timeout exception.

Upvotes: 0

Views: 494

Answers (2)

Aleksey Isachenkov
Aleksey Isachenkov

Reputation: 1240

You can see in the description of Future.foreach:

Asynchronously processes the value in the future once the value becomes available.

WARNING: Will not be called if this future is never completed or if it is completed with a failure.

If you want to use Future.foreach, you should write something like:

x.map(Success(_)).recover({case exception => Failure(exception)}).foreach(println) 

Upvotes: 2

atline
atline

Reputation: 31664

Try next:

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

Future foreach just handle success case, akka.pattern.AskTimeoutException: belongs to Failure, you need to handle it by your code.

Or next also ok:

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

Upvotes: 1

Related Questions