hotmeatballsoup
hotmeatballsoup

Reputation: 595

Performing actor lookup with Akka actorFor

I have the following Akka actor:

public class MyActor extends AbstractActor {
  protected Logger log = LoggerFactory.getLogger(this.getClass());

  @Override
  public Receive createReceive() {
      return receiveBuilder()
          .matchAny(message -> {

            String myFullName = self().path().toString();
            String myName = self().path().name();
            ActorRef reincarnatedMe = context().actorFor(self().path().name());
            String reincarnatedFullName = reincarnatedMe.path().toString();
            String reincarnatedName = reincarnatedMe.path().name();

            log.info("myFullName: {}", myFullName);
            log.info("myName: {}", myName);
            log.info("reincarnatedFullName: {}", reincarnatedFullName);
            log.info("reincarnatedName: {}", reincarnatedName);

          }).build();
  }
}

At runtime it produces this output:

05:43:14.617 [MySystem-akka.actor.default-dispatcher-4] INFO myapp.actors.MyActor - myFullName: akka://MySystem/user/MyActor
05:43:14.623 [MySystem-akka.actor.default-dispatcher-4] INFO myapp.actors.MyActor - myName: MyActor
05:43:14.623 [MySystem-akka.actor.default-dispatcher-4] INFO myapp.actors.MyActor - reincarnatedFullName: akka://MySystem/user/MyActor/MyActor
05:43:14.623 [MySystem-akka.actor.default-dispatcher-4] INFO myapp.actors.MyActor - reincarnatedName: MyActor

My understanding was that context().actorFor(...) doesn't create a new actor, rather it finds an existing actor that matches the path/string you provide and returns a reference to it.

However, it appears that in my code above, self() becomes the parent of reincarnatedMe as evidenced by myFullName simply being "MySystem/user/MyActor" whereas reincarnatedFullName is "MySystem/user/MyActor/MyActor"...

Am I reading this right? If so, how can I invoke context().actorFor(...) (or any other method for that matter) such that myFullName becomes the same as reincarnatedFullName (so that self() and reincarnatedMe reference the same actor? And if I'm not reading this right, why is myFullName different than reincarnatedFullName?


Update:

public class AnotherActor extends AbstractActor { ... }

// Inside MyActor#createReceive:
ActorSelection anotherActorSel = context().actorSelection("AnotherActor");

anotherActorSel.tell(new SomeMessage(), self());

Upvotes: 1

Views: 238

Answers (1)

Rob Crawford
Rob Crawford

Reputation: 556

First, ActorContext.actorFor(String) is deprecated in favor of ActorContext.actorSelection(String). This method returns an ActorSelection, but you can still send a message to an ActorSelection (such as an Identify, which response with an ActorIdentity message automatically).

The documentation for the actorFor method says that, "Absolute URIs like akka://appname/user/actorA are looked up as described for look-ups by actorOf(ActorPath)." I can't find documentation on an actorOf(ActorPath) method, but the other actorOf methods state they create new actors, so I suspect this does the same. The behavior you've found is likely the reason for the deprecation -- or because it was deprecated and the methods used for something else.

Upvotes: 3

Related Questions