Why when I select an absolute path with ActorContext it doesn't works (the actor isn't correctly selected and doesn't receive the HelloResponse message) ?
//From Actor2:
//This doesn't work (Message never received)
context.actorSelection("/user/actor1") ! HelloResponse("hello back1")
//This works (actor 1 receives the message)
context.system.actorSelection("/user/actor1") ! HelloResponse("hello back2")
I'm newbie to Scala/Akka but reading documentation it seems that should work.
This is a bug, thanks for asking: https://www.assembla.com/spaces/ddEDvgVAKr3QrUeJe5aVNr/tickets/3276
When you use context.actorSelection
inside of an actor, what you are saying is find an actor under this current actors control (started by/supervised by). Since actor1 was probably not started by actor2 (or is not supervised by actor2), then it won't resolve to anything. If actor1 was actually owned/started by actor2 then you could probably do context.actorSelection("/actor1")
to get that child actor of actor2. The reason context.system.actorSelection
works is because you are going all the way "up" to system
first before starting your search and fully qualifying the path to the actor. System "owns" actor1 if you started it up as system.actorOf
, so using that path will allow you to get to it starting from system
.
A little code to show what I mean:
class Actor1 extends Actor{
override def preStart = {
context.actorOf(Props[Actor2], "actor2")
}
def receive = {
case _ =>
}
}
class Actor2 extends Actor{
override def preStart = {println("my path is: " + context.self.path)}
def receive = {
case _ =>
}
}
object FutureTesting {
def main(args: Array[String]) {
val sys = ActorSystem("test")
implicit val ec = sys.dispatcher
//Starting an Actor2 from system
sys.actorOf(Props[Actor2], "actor2")
//Starting an Actor1 from system which in turn starts an Actor2
sys.actorOf(Props[Actor1], "actor1")
}
}
When you run this example, you will see:
my path is: akka://test/user/actor1/actor2
my path is: akka://test/user/actor2
So you can see that I have 2 instances of Actor2
running in my system; one spawned directly from sys
tied to /user/actor2
as it's lookup path and one started from an instance of Actor1
tied to /user/actor1/actor2
for its path.
The actor system is hierarchical and this example shows that. The ActorSystem
itself is the root to everything. Selecting actors is then similar to XPath in that the context that you are issuing the select from matters.
From actor2
you will need to use
context.actorSelection("/actor1")
I agree it is not intuitive given the metaphor is a filesystem and when using a filesystem a leading /
is an absolute path meaning start at the root. Also it is inconsistent with actorFor
because
context.actorFor("/user/actor1")
returns the top level Actor1
(see Absolute and Relative Paths)
EDIT - this was a bug that was fixed in Akka 2.1.4 (see Roland's answer). From 2.1.4 onwards you can use context.actorSelection("/user/actor1")
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With