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.
Actors process one message at a time, and do not process the next message until
receivehas 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 thereceivecall for first message is complete. SoAwait.result((self ? ...is always going to fail when the?times out.The simple fix is to send both queries to
childrather than sending the first one toself. 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, not0. As it stands the code will always return0.