1
votes

What is the behavior if I send a message to an Actor pool whose Actors then, upon receiving that message, send a message to self? In this case, is sending to self going to send messages to the pool, or to the specific Actor instance that sent the message?

Pseudocode of this scenario would look like the following

...
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
Assume in the above code that SomeActor is the only type of Actor in the system. This helps clarify what the last code comment is asking. Ignore the fact that someDependency is never used - it's only there to more accurately reflect the actual code I have in my real application.josiah

1 Answers

4
votes

self always points to an actor's own ActorRef:

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

When the routee sends "hello world" to self, it's sending that string to itself. This "hello world" string will then be captured in the case msg @ "hello world" => clause, and the actor will print the message.

Do I know that the same Actor insntance that sent me "hello world" is also going to execute "println(msg)"...

An external actor could send either "hello" or "hello world" to the router. The router would then forward the message to one of the routees. For a routee to determine whether a "hello world" message was from itself or an external actor, the routee would have to inspect the value of sender (e.g., it could check whether sender was equal to self).

...or could any Actor in the Pool have sent the "hello world" message?

It's unclear what you're asking here. Routees typically don't communicate with each other.

How would I send a message back to the Pool, instead of to 'self'? Would I need to pass the reference to the Actor Pool as a dependency, even though my Actor is a member of the Pool it wants to send messages to?

A routee doesn't need to know about other routees or the router. If you want to send a message back to the pool, let the original sender (i.e., the actor that sent the message to the router) do this. In other words, have your routee send the message to sender, and let that actor send the message back to the router. To emphasize this point, sender in this context is not the router/pool, but the original sender (there are a few exceptions to this, as described in the 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

You can read more about routing here.