Scala 在Akka中,当消息发送到参与者池时,“self”是否包含对参与者实例或整个池的引用?

Scala 在Akka中,当消息发送到参与者池时,“self”是否包含对参与者实例或整个池的引用?,scala,concurrency,akka,actor,Scala,Concurrency,Akka,Actor,如果我向一个参与者池发送一条消息,而该参与者池的参与者在收到该消息后,会向self发送一条消息,这是什么行为?在这种情况下,sending to self将向池发送消息,还是向发送消息的特定Actor实例发送消息 此场景的伪代码如下所示 ... val system: ActorSystem = ActorSystem() val actorPool: ActorRef = system.actorOf( Props(new SomeActor(someDependency)) .w

如果我向一个参与者池发送一条消息,而该参与者池的参与者在收到该消息后,会向self发送一条消息,这是什么行为?在这种情况下,sending to self将向池发送消息,还是向发送消息的特定Actor实例发送消息

此场景的伪代码如下所示

...
val system: ActorSystem = ActorSystem()
val actorPool: ActorRef = system.actorOf(
  Props(new SomeActor(someDependency))
    .withRouter(RoundRobinPool(conf.someActorPoolSize))
actorPool ! "hello"

class SomeActor(someDependency: SomeDependency) extends Actor {
  def receive = {
    case hello @ "hello" => self ! hello + " world"
    // ^Does the above send to the entire Pool, or does this specific
    // Actor just send the message directly to itself?
    case msg @ "hello world" => println(msg)
    // ^Do I know that the same Actor insntance that sent me "hello world"
    // is also going to execute "println(msg)", or could any Actor in the
    // Pool have sent the "hello world" message?
  }
}
始终指向演员自己的演员如果:

当routee向self发送hello world时,它正在向自身发送该字符串。然后在case msg@helloworld=>子句中捕获这个helloworld字符串,参与者将打印消息

我知道那个送我“你好世界”的演员吗 也将执行printlnmsg

外部参与者可以向路由器发送hello或hello world。然后,路由器将消息转发给其中一个路由器。对于routee,要确定hello world消息是来自自身还是外部参与者,routee必须检查发送者的值,例如,它可以检查发送者是否等于self

…或者池中的任何一个演员都会发送hello world消息吗

不清楚你在问什么。路由者通常不相互通信


我如何将消息发送回池,而不是“self”?我是否需要将对Actor池的引用作为依赖项传递,即使我的Actor是它要向其发送消息的池的成员

路由器不需要知道其他路由器或路由器。如果要将消息发送回池,请让原始发件人(即,将消息发送到路由器的参与者)执行此操作。换句话说,让您的路由器将消息发送给发送者,并让该参与者将消息发送回路由器。为了强调这一点,此上下文中的发送方不是路由器/池,而是原始发送方。有一些例外情况,如中所述:

您可以阅读有关路由的更多信息。

始终指向参与者自己的ActorRef:

当routee向self发送hello world时,它正在向自身发送该字符串。然后在case msg@helloworld=>子句中捕获这个helloworld字符串,参与者将打印消息

我知道那个送我“你好世界”的演员吗 也将执行printlnmsg

外部参与者可以向路由器发送hello或hello world。然后,路由器将消息转发给其中一个路由器。对于routee,要确定hello world消息是来自自身还是外部参与者,routee必须检查发送者的值,例如,它可以检查发送者是否等于self

…或者池中的任何一个演员都会发送hello world消息吗

不清楚你在问什么。路由者通常不相互通信


我如何将消息发送回池,而不是“self”?我是否需要将对Actor池的引用作为依赖项传递,即使我的Actor是它要向其发送消息的池的成员

路由器不需要知道其他路由器或路由器。如果要将消息发送回池,请让原始发件人(即,将消息发送到路由器的参与者)执行此操作。换句话说,让您的路由器将消息发送给发送者,并让该参与者将消息发送回路由器。为了强调这一点,此上下文中的发送方不是路由器/池,而是原始发送方。有一些例外情况,如中所述:


您可以阅读有关路由的更多信息。

我如何将消息发送回池,而不是发送回“self”?我是否需要将对Actor池的引用作为依赖项传递,即使我的Actor是它要向其发送消息的池的成员?假设SomeActor是唯一发送hello world消息的对象,因此我们可以保证hello world来自SomeActor。@josiah:已更新。@richj:这是错误的。routee中的发送方是对原始发送方的引用,而不是对路由器的引用。这是因为路由器将消息转发给它的路由对象。@chunjef-谢谢。我应该说context.parent,正如文档的Senders部分所解释的那样,将消息发送回路由器/池。这对于与监管相关的消息可能很有用,因为原始发件人不需要参与其中。我如何将消息发送回池,而不是“self”?我是否需要将对Actor池的引用作为依赖项传递,即使我的Actor是它要向其发送消息的池的成员?假设SomeActor是唯一发送hello world消息的对象,因此我们可以保证hello world来自SomeActor。@josiah:已更新。@richj:这是错误的。routee中的发送方是对原始发送方的引用,而不是对路由器的引用。这是因为路由器转发
给它的乘客的信息。@chunjef-谢谢。我应该说context.parent,正如文档的Senders部分所解释的那样,将消息发送回路由器/池。这对于与监控相关的消息可能很有用,因为原始发送者不需要参与其中。这有助于澄清最后一条代码注释的问题。忽略someDependency从未被使用这一事实——它只是为了更准确地反映我在实际应用程序中的实际代码。这有助于澄清最后一条代码注释的问题。忽略这样一个事实:someDependency从未被使用过——它只是为了更准确地反映我在实际应用程序中的实际代码。
def receive = {
  case hello @ "hello" =>
    self ! hello + " world" // sends "hello world" to itself
  case msg @ "hello world" =>
    println(msg)
client            --> router --> [routee1, routee2, etc.]
(original sender)                // sender in a routee is a reference to client, because
                                 // the router forwards the messages to the routees