Akka : the proper use of `ask` pattern?

akka, asynchronous, future, scala

Solution

The official Akka documentation says that Await.result will cause the current thread to block and wait for the Actor to 'complete' the Future with it's reply.

It is strange that your code blocks there forever, do you have only one thread for all your application?

Anyway I guess a more "idiomatic" way to code it would be to use a callback on the future success.

def receive = {
    case "ping_other" => {
      val selection = context.actorSelection("../node_1")
      log.info("Sending ping to node_1")
      val future: Future[String] = ask(selection, "ping").mapTo[String]
      future.onSuccess { 
         case result : String ⇒ log.info("Got result " + result)
      }
    }
...

Problem

I'm trying to grok `Futures` and ask pattern in akka. So, I make two actors, and one asking another to send him back a message. Well, according to akka's `Futures` documentation, actor should ask(`?`) for message and it shall give him a `Future` instanse. Then actor should block (using `Await`) to get `Future` results. Well, I never get my future done. Why is that? Code is: ``` package head_thrash import akka.actor._ import akka.util.Timeout import scala.concurrent.Await import scala.concurrent.duration._ object Main extends App { val system = ActorSystem("actors") val actor1 = system.actorOf(Props[MyActor], "node_1") val actor2 = system.actorOf(Props[MyActor], "node_2") actor2 ! "ping_other" system.awaitTermination() Console.println("Bye!") } class MyActor extends Actor with ActorLogging { import akka.pattern.ask implicit val timeout = Timeout(100.days) def receive = { case "ping_other" => { val selection = context.actorSelection("../node_1") log.info("Sending ping to node_1") val result = Await.result(selection ? "ping", Duration.Inf) // <-- Blocks here forever! log.info("Got result " + result) } case "ping" => { log.info("Sending back pong!") sender ! "pong" } } } ``` If I change `Duration.Inf` to `5.seconds`, then actor waits 5 seconds, tells that my future is Timeouted (by throwing `TimeoutException`), and then other actor finally replies with needed message. So, no async happens. Why? :-( How should I properly implement that pattern? Thanks.

Original source