I have a java object which is not an actor which selects actors from an actor system with actorSelection(Path)). It is possible, that the selected actor does not exist in the system.
In the Java Api ask() does not exist for ActorSelection, so I can not send and Identify message to the actor selection and use the sender of the response.
I tried to solve the problem by sending the message to the actor anyway via the actor selection and then reacting to the deadletter. But I don't get any deadletters.
How can I check with the ActorSelection if the actor is alive or does not exist?
ActorSystem system = ActorSystem.create("test"); //create test actor system.actorOf(Props.create(TestActor.class), "testActor"); //add dead letter listener to the system ActorRef eventBusActor = asys.actorOf(Props.create(EventBusActor.class), "eventbusactor"); system.eventStream().subscribe(eventBusActor, DeadLetter.class); //This works. The test actor receives the message ActorSelection a1 = asys.actorSelection("/user/testActor"); a1.tell("hello", ActorRef.noSender()); //This does not work and does not send dead letters ActorSelection a2 = asys.actorSelection("/user/doesnotexist"); a2.tell("hello", ActorRef.noSender()); //Does not compile, because ask needs an ActorRef as first argument ActorSelection a3 = asys.actorSelection("/user/test"); Future f = Patterns.ask(a3, new Identify(), 1000);
What is an Actor in Akka? An actor is essentially nothing more than an object that receives messages and takes actions to handle them. It is decoupled from the source of the message and its only responsibility is to properly recognize the type of message it has received and take action accordingly.
The good news is that Akka actors conceptually each have their own light-weight thread, which is completely shielded from the rest of the system. This means that instead of having to synchronize access using locks you can write your actor code without worrying about concurrency at all.
Actors communicate using asynchronous messages. This ensures that the sender does not stick around waiting for their message to be processed by the recipient. Instead, the sender puts the message in the recipient's mailbox and is free to do other work.
I recently found the ActorSelection.resolveOne method:
val name = "myActor" implicit val timeout = 5000 // Timeout for the resolveOne call system.actorSelection(name).resolveOne().onComplete { case Success(actor) => actor ! message case Failure(ex) => val actor = system.actorOf(Props(classOf[ActorClass]), name) actor ! message }
One problem I'm still investigating is, the method where this is defined might be called concurrently (from other actors). Therefore it's possible to get a race condition where you try to create the actor twice if the resolveOne call fails because the actor is still being created. This might or might not be an issue for your use case
It looks like Akka left off support for ActorSelection
on the java api for ask
. I played with the code a little and I found something that works though. See if this code works for you:
import java.util.concurrent.TimeUnit; import scala.concurrent.Await; import scala.concurrent.Future; import akka.actor.ActorIdentity; import akka.actor.ActorRef; import akka.actor.ActorSelection; import akka.actor.ActorSystem; import akka.actor.Identify; import akka.actor.Props; import akka.pattern.AskableActorSelection; import akka.util.Timeout; public class AskTest { public static void main(String[] args) throws Exception{ ActorSystem sys = ActorSystem.apply("test"); sys.actorOf(Props.create(TestActor.class), "mytest"); ActorSelection sel = sys.actorSelection("/user/mytest"); Timeout t = new Timeout(5, TimeUnit.SECONDS); AskableActorSelection asker = new AskableActorSelection(sel); Future<Object> fut = asker.ask(new Identify(1), t); ActorIdentity ident = (ActorIdentity)Await.result(fut, t.duration()); ActorRef ref = ident.getRef(); System.out.println(ref == null); } }
I just looked at how the scala ask support worked and hooked into it via java. This worked for me; I'm hoping it works for you.
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