在Akka中,当消息被发送到Actor Pool时,'self'是否持有对Actor实例或整个Pool的引用?

时间:2017-12-04 17:09:08

标签: scala concurrency akka actor

如果我向Actor池发送消息的行为是什么,Actors接收到该消息后,会向self发送消息?在这种情况下,发送到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?
  }
}

1 个答案:

答案 0 :(得分:4)

self始终指向演员自己的ActorRef

def receive = {
  case hello @ "hello" =>
    self ! hello + " world" // sends "hello world" to itself
  case msg @ "hello world" =>
    println(msg)

当受让人向"hello world"发送self时,它会将该字符串发送给自己。然后将在"hello world"子句中捕获此case msg @ "hello world" =>字符串,并且actor将打印该消息。

  

我是否知道发送给我的同一个演员的咒语"你好世界"   也将执行" println(msg)" ...

外部参与者可以向路由器发送"hello""hello world"。然后路由器将消息转发到其中一个路由器。对于确定"hello world"消息是来自自己还是外部参与者的路由者,被告必须检查sender的值(例如,它可以检查sender是否等于self)。

  

......或者游泳池中的任何演员都可以发送" hello world"消息?

目前还不清楚你在这里问的是什么。路线通常不会相互沟通。

  

如何向游泳池发送消息,而不是发送给自己'?我是否需要将对Actor池的引用作为依赖项传递,即使我的Actor是它想要向其发送消息的Pool的成员?

他们不需要了解其他路线或路由器。如果要将消息发送回池,请让原始发件人(即将消息发送到路由器的actor)执行此操作。换句话说,让你的路由器将消息发送到sender,让该actor将消息发送回路由器。为了强调这一点,sender在此上下文中路由器/池,而是原始发件人(有一些例外情况,如documentation中所述) :

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

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