Stackoverflow Exception using Scala actors and receiveWithin
After some time this actor fills out stack. Possible solutions ?
object Puller extends Actor {
def act() = {
receiveWithin(2000) {
case Stop => println("stoping puller")
exit()
case Noop => println("nothing happens")
act()
case TIMEOUT => doPull
act()
}
}
def doPull() = // stuff...开发者_Go百科
}
I'm unhappy to find this code in Programming in Scala.
Your act
is not tail-recursive. You can modify it as follows:
@tailrec // in the presence of this annotation, the compiler will complain, if the code is not tail-recursive
def act() = {
receiveWithin(2000) {
case Stop => println("stoping puller"); exit()
case Noop => println("nothing happens")
case TIMEOUT => doPull
}
act()
}
Well, it stack overflows for very obvious reasons; it's recursive but not tail-recursive. There are two options here:
Either: Use a while loop:
def act() =
while(true) {
receiveWithin(2000) {
case Stop => println("stoping puller"); exit()
case Noop => println("nothing happens")
case TIMEOUT => doPull
}
}
Or: Use loop
and react
(which has the added benefit of being scalable by decoupling the actor from hogging a single thread).
def act() =
loop {
reactWithin(2000) {
case Stop => println("stoping puller"); exit()
case Noop => println("nothing happens")
case TIMEOUT => doPull
}
}
If this code exists in Programming in Scala, it's probably meant more as a proof-of-concept, rather than viable production code. In fact, from memory, it goes on to explain how the recursive act
calls can be avoided.
精彩评论