简体   繁体   中英

Actor selection

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.

这是一个错误,感谢您的询问: 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") .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM