开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜