Why another variable or a copy of a variable?
I have a simple program in Scala using Akka, and I have the following scenario: I have two different types of ordinary members ( FooActor
and BarActor
). FooActor
receives ActorRef
via a constructor that represents some actor to whom it FooActor
should deliver its response (original sender). This original sender is listed BarActor
. My question is, why does the other pass the local in the constructor sender
and pass in a local variable that was previously assigned a value sender
? Are they links or do they contain a link inside an obect? What's going on under the hood? Thank you. Here is the code:
import akka.actor._
case class foo(x: Int) // some dummy message to test
class FooActor(originalSender: ActorRef) extends Actor {
println("[" + self.path + "] originalSender = " + originalSender) // print the sender
override def receive = {
// (...)
case _ =>
}
}
class BarActor extends Actor {
override def receive = {
case foo(x) =>
// variant 1: this prints deadLetters as the sender in the FooActor
context.actorOf(Props(new FooActor(sender)), "foo" + x)
// variant 2: this prints the original sender correctly
// val originalSender = sender
// context.actorOf(Props(new FooActor(originalSender)), "foo" + x)
case _ =>
}
}
object Main {
def main(args: Array[String]): Unit = {
val system = ActorSystem("my-system")
val sender = system.actorOf(Props[BarActor], "sender") // this would be the original sender
val bar = system.actorOf(Props[BarActor], "bar") // this is the intermediate actor, who passes the sender
bar.tell(foo(1), sender)
}
}
source to share
The answer lies in the method signature Props.apply
.
def apply[T <: Actor: ClassTag](creator: ⇒ T): Props = ...
It takes a parameter by name. This, combined with the fact that sender()
inside the actor it is a method and not a val, leads you to a situation where it sender()
is called after a while (when evaluated creator
), where the actor no longer processes the original message, thus returning a reference to DeadLetters
.
source to share