Akka Actor 必须区分消息传递时是否需要返回 future 吗?

发布于 2025-01-02 08:26:34 字数 1489 浏览 3 评论 0原文

据我了解,演员可以用“发射后不管”风格发送消息!运算符,或带有 ? 的“发送并接收未来”风格操作员。通过 ? 传递消息的演员必须调用 self.reply,否则发送者将收到超时异常。另一方面,演员通过 !如果消息不是从另一个参与者传递的,则不能有 self.reply。

我的问题是,Actor 是否应该在编译时知道它是否会被调用!或者 ? ???或者如果 self.reply 的必要性可以在运行时确定,那么如何确定呢?也许涉及 self.tryReply,但 akka 文档似乎暗示尝试回复失败是一个错误情况,而如果发送者不是参与者,如果消息通过!

编辑:

这是一些代码:

package akTest

import akka.actor.Actor

object Main1 {
  val worker = Actor.actorOf[ak].start()

  def main(args: Array[String]) {
    val resp = worker ? "Hi"
    resp.get
    println(resp)
  }
}

class ak extends Actor {
  def receive = {
    case msg:String  => {
      val response = "Received: " + msg
      println(response)
      response
    }
  }
}

这得到 线程“main”中的异常 akka.dispatch.FutureTimeoutException: Futures timed out after [4995] milliseconds

所以我向 actor 添加了一个 self.reply:

class ak extends Actor {
  def receive = {
    case msg:String  => {
      val response = "Received: " + msg
      println(response)
      self.reply(response)
      response
    }
  }
}

此更改修复了超时错误。但现在如果我有一个发送即发即忘消息的 Main2,

object Main2 {
  val worker = Actor.actorOf[ak].start()

  def main(args: Array[String]) {
    val resp = worker ! "Hi"
    println(resp)
  }
}

则会产生一个新错误: [ERROR] [2/1/12 2:04 PM] [akka:event-driven:dispatcher:global- 1] [本地演员参考] 范围内没有发送者,无法回复。

我如何编写我的参与者以消除其响应方式与发送者调用方法之间的耦合?我不想有 1 个版本的演员!和演员的第二个版本?

As I understand it, an actor can be sent a message "fire and forget" style with the ! operator, or "Send-And-Receive-Future" style with the ? operator. An actor that is passed a message via ? must call a self.reply or the sender will receive a timeout exception. On the other hand, an actor that is passed a message via ! cannot have self.reply if the message is not being passed from another actor.

My question is, is the Actor supposed to know at compile time whether it will be invoked with ! or ? ??? Or if the necessity of self.reply can be determined at runtime, how can this be determined? Perhaps self.tryReply is involved, but the akka documentation seems to imply that a failed attempt to reply is an error case, whereas if the sender is not an actor, it is not really an error to fail to reply if the message is passed with !

Edit:

Here's some code:

package akTest

import akka.actor.Actor

object Main1 {
  val worker = Actor.actorOf[ak].start()

  def main(args: Array[String]) {
    val resp = worker ? "Hi"
    resp.get
    println(resp)
  }
}

class ak extends Actor {
  def receive = {
    case msg:String  => {
      val response = "Received: " + msg
      println(response)
      response
    }
  }
}

This gets
Exception in thread "main" akka.dispatch.FutureTimeoutException: Futures timed out after [4995] milliseconds

So I add a self.reply to the actor:

class ak extends Actor {
  def receive = {
    case msg:String  => {
      val response = "Received: " + msg
      println(response)
      self.reply(response)
      response
    }
  }
}

This change fixes the timeout error. But now if I have a Main2 which sends a fire and forget message:

object Main2 {
  val worker = Actor.actorOf[ak].start()

  def main(args: Array[String]) {
    val resp = worker ! "Hi"
    println(resp)
  }
}

, a new error is produced: [ERROR] [2/1/12 2:04 PM] [akka:event-driven:dispatcher:global-1] [LocalActorRef]
No sender in scope, can't reply.

How can I write my actor to eliminate the coupling between its manner of response and the sender's method of invoking? I don't want to have 1 version of the actor for ! and a second version of the actor for ?

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

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

发布评论

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

评论(1

芯好空 2025-01-09 08:26:34

如果 senderFuture.isDefined 那么你有一个 future 可以回复

if senderFuture.isDefined then you have a future to reply to

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