akka如何启动主任务并阻止其完成?

发布于 2024-11-07 14:01:06 字数 734 浏览 4 评论 0原文

我正在尝试在 scala 中开始使用 akka。在主 scala 线程中,我想启动一个 akka actor,向它发送一条消息,然后阻塞,直到该 actor 终止。最好的方法是什么?

例如,我有一个测试参与者,它只是重复地向自身发送消息:

class Incrementer() extends Actor {

  val maxMessages = 5
  var counter = 0

  def receive() = {
    case DoIncr() => {
      if (counter < maxMessages) {
        counter += 1
        self ! DoIncr()
      } else {
        self.stop()
      }
    }
  }
}

并且通过以下方式调用它:

val inc = actorOf(new Incrementer()).start()
val result = inc !! DoIncr()
println(result) // this should block this thread, but it doesn't seem to.

// do other stuff

该块只需要 5,000 多毫秒来执行,而不是我期望的几毫秒,所以它似乎与默认未来超时 - 并且程序实际上不会终止。我真正想做的就是对发送 x 条消息的性能进行计时。这是怎么回事?

I'm trying to get started with akka in scala. In the main scala thread I'd like to start an akka actor, send one message to it, and block until that actor terminates. What is the best way to do this?

For example I have a test actor that just repeatedly sends messages to itself:

class Incrementer() extends Actor {

  val maxMessages = 5
  var counter = 0

  def receive() = {
    case DoIncr() => {
      if (counter < maxMessages) {
        counter += 1
        self ! DoIncr()
      } else {
        self.stop()
      }
    }
  }
}

and it is invoked via:

val inc = actorOf(new Incrementer()).start()
val result = inc !! DoIncr()
println(result) // this should block this thread, but it doesn't seem to.

// do other stuff

That block takes just over 5,000 ms to execute instead of what I expect to be a few ms, so it seems to have to do with a default future timeout - and the program does not actually terminate. All I'm really trying to do is time the performance of sending x number of messages. What's going on here?

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

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

发布评论

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

评论(1

只为一人 2024-11-14 14:01:06

正如 Viktor 提到的,为了使 !! 成功终止,您必须回复该消息。您看到的是演员的默认超时 5 秒延迟,这是可配置的。更多信息请访问 Akka 网站

如果您使用 forward 而不是 ! 发送消息,则 self.reply 将响应原始发件人。

您发送给 Akka actor 的第一条消息执行一些在处理其他消息时不会发生的设置。请务必在您的时间安排中考虑到这一点。

更正后的代码如下:

import akka.actor._

object DoIncr

class Incrementer extends Actor {
  val maxMessages = 5
  var counter = 0

  def receive = {
    case DoIncr =>
      if (counter < maxMessages) {
        counter += 1
        self forward DoIncr
      } else {
        self.reply(()) // replying with () since we have nothing better to say
        self.stop()
      }
  }
}

旁白:我做了一些其他更改,以使您的代码符合惯用的 Scala。您的代码无需进行这些更改即可工作,但它现在看起来像更典型的 Scala 代码。

  • 不推荐使用没有参数列表的案例类。使用对象来代替。
  • 如果你的类没有参数列表,可以省略括号
  • Actorreceive方法没有parens;你的实现类也不应该有它们。
  • 这纯粹是风格问题,但 case 语句的主体不需要大括号。

As Viktor mentioned, in order for !! to terminate successfully, you have to reply to the message. The 5 second delay you are seeing the actor's default timeout, which is configurable. More info can be found on the Akka site.

If you use forward to send the message instead of !, then self.reply will respond to the original sender.

The first message you send to an Akka actor performs some setup that doesn't happen when processing other messages. Be sure to take that into account for your timings.

Corrected code would be:

import akka.actor._

object DoIncr

class Incrementer extends Actor {
  val maxMessages = 5
  var counter = 0

  def receive = {
    case DoIncr =>
      if (counter < maxMessages) {
        counter += 1
        self forward DoIncr
      } else {
        self.reply(()) // replying with () since we have nothing better to say
        self.stop()
      }
  }
}

Aside: I made a few other changes to get your code in line with idiomatic Scala. Your code works without these changes, but it now looks like more typical Scala code.

  • Case classes without parameter lists have been deprecated. Use objects instead.
  • If you have a class without a parameter list, you can omit the parenthesis
  • Actor's receive method does not have parens; your implementing class shouldn't have them either.
  • It's purely a matter of style, but the body of a case statement does not require braces.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文