Await.result always hangs/timeout and never returns result (Scala - Akka actors)

44 Views Asked by At

To make an inefficient story short, I am trying to make a Scala actor system which computes Fibonacci numbers. However, the Await.result() lines always timeout, and I'm not sure what the issue is.

class FibMachine extends Actor {
    implicit val timeout: Timeout = Timeout(5L, TimeUnit.SECONDS)
    override def receive: Receive = {
        case 0 => sender ! 0
        case 1 => sender ! 0
        case x: Int if x > 1 => {
            val child = context.actorOf(Props(new FibMachine()))
            val self_num: Int = Await.result((self ? (x - 1)).mapTo[Int], timeout.duration)
            val child_num: Int = Await.result((child ? (x - 2)).mapTo[Int], timeout.duration)
            child ! PoisonPill
            sender ! self_num + child_num
        }
    }
}

What is the simplest way to fix this issue?

Searched online, didn't get any useful results.

1

There are 1 best solutions below

0
Tim On

Actors process one message at a time, and do not process the next message until receive has returned for the current message. An actor cannot send a message to itself and then block waiting for a reply because that second message cannot be processed until the receive call for first message is complete. So Await.result((self ? ... is always going to fail when the ? times out.

The simple fix is to send both queries to child rather than sending the first one to self. It will be massively inefficient and probably run out of resources for large numbers but at least it won't hang.

It is also worth noting that the first two terms of the Fibonacci sequence are 1, not 0. As it stands the code will always return 0.