使用 Scala actor 和 receiveWithin 时出现 Stackoverflow 异常

发布于 2024-11-09 14:05:40 字数 362 浏览 0 评论 0原文

一段时间后,该演员填满了堆栈。可能的解决方案?

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...
}

我很高兴在《Scala 编程》中找到这段代码。

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...
}

I'm unhappy to find this code in Programming in Scala.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逆流 2024-11-16 14:05:40

您的 act 不是尾递归的。您可以按如下方式修改:

  @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()
  }

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()
  }
长亭外,古道边 2024-11-16 14:05:40

嗯,它的堆栈溢出有非常明显的原因;它是递归的,但不是尾递归的。这里有两个选项:

要么:使用 while 循环:

def act() = 
  while(true) {
    receiveWithin(2000) {
      case Stop    => println("stoping puller"); exit()
      case Noop    => println("nothing happens")
      case TIMEOUT => doPull
    }
  }

:使用 loopreact (其中有通过将参与者与占用单个线程分离来实现可扩展的额外好处)。

def act() = 
  loop {
    reactWithin(2000) {
      case Stop    => println("stoping puller"); exit()
      case Noop    => println("nothing happens")
      case TIMEOUT => doPull
    }
  }

如果此代码存在于Scala 编程中,那么它可能更多地意味着概念验证,而不是可行的生产代码。事实上,根据记忆,它继续解释了如何避免递归 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文