How to watch remote Akka Actor?

1.4k views Asked by At

I am learning akka-remote and one of the things I do in my LocalActorSystem is getting remote actor reference and send messages to him

class LocalActor extends Actor {
  val remote = context.actorSelection("akka.tcp://[email protected]:5150/user/RemoteActor")
  var counter = 0

  def receive = {
    case "START" =>
      remote ! "Hello from the LocalActor"
    case msg: String =>
      println(s"LocalActor received message: '$msg'")
      if (counter < 5) {
        sender ! "Hello back to you"
        counter += 1
      }
  }
}

My Remote looks like

object Remote extends App {
  val system = ActorSystem("HelloRemoteSystem", ConfigFactory.load("remote"))
  val remoteActor = system.actorOf(Props[RemoteActor], name = "RemoteActor")
  remoteActor ! "The RemoteActor is alive"
}

class RemoteActor extends Actor {
  def receive = {
    case msg: String =>
      println(s"RemoteActor received message '$msg'")
      sender ! "Hello from the RemoteActor"
  }
}

I also wanted to watch remoteActor so that if its dead, LocalActorSystem get to know. So I did

  val remote = context.actorSelection("akka.tcp://[email protected]:5150/user/RemoteActor")
  context watch remote

but then compiler fails with following message

enter image description here

Question

  1. How come I am able to send message to ActorSelection since it is not Actor?
  2. How can I watch RemoteActor?

Update
However, the deprecated API does not complain

val remote = context.actorFor("akka.tcp://[email protected]:5150/user/RemoteActor")
  context watch remote
1

There are 1 answers

0
cmbaxter On BEST ANSWER

When you do a lookup via actorSelection, that type of object you get back is an ActorSelection and not an ActorRef. Now, an ActorSelection does support both tell (!) and ask (?) so you can interact with it the same way you would an ActorRef. But an looking up actors via actorSelection supports the concept of a wild card, so the ActorSelection you get back potentially represents more than one actor and would allow you to send messages to more than one actor. For instance, if you did :

system.actorSelection("/user/foo/*")

this would give you an ActorSelection for all children under the parent ActorRef bound to the name foo. If there were two children and you send a message via that ActorSelection, that message would be delivered to both children.

In your case, it looks like you are looking up a single actor instance. In that case, you can get an ActorRef from your ActorSelection by calling resolveOne on it. This will return a Future[ActorRef] that when completed will provide you with an ActorRef that you can watch remotely. You could also send the ActorSelection an Identify message and wait for the ActorIdentity response containing the ref to watch.

You should check out the docs here, specifically the Identifying Actors via Actor Selection section.