Reputation: 14309
I have three remote Akka actors: A, B and C. A sends a message to B and B saves A's reference (see below). In addition, I need B to send A's reference to C. How can I do that? The Java code for B looks like this:
public class B extends UntypedActor {
//---------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void onReceive(Object object) throws Exception {
if (refA == null) {
refA = getSender();
}
// how do I send refA to C???
refC.tell(refA, getSelf()); // <== like this?
}
// set during onReceive
private ActorRef refA = null;
// initialized in constructor
private final ActorRef refC;
}
I just checked and ActorRef
is Serializable
so in theory my solution proposed above should work but is there a different/official/cleaner way to do it?
Upvotes: 1
Views: 1281
Reputation: 2086
If actor C only needs to have a reference to actor A, you only need to change the line in Actor B with the tell method to:
refC.tell(refA, getSender());
If actor C must have a reference of both, Actor A and Actor B, then you can do two things:
1) Use the code you provided.
2) Use the method getContext().actorSelection("actor_name") in the Actor C to fetch the Actor A. How actorSelection works is described in the Akka Documentation but it will look as follows:
public class ActorC extends UntypedActor {
private static String ID="whateverID";
private ActorRef actorA;
{
getContext().actorSelection("akka.tcp://app@host:port/user/actorAName").
tell(new Identify(ID), getSelf());
}
//As an alternative, if you need the ActorA initialized in the constructor,
//you can use the .resolveOne method.
//public ActorC(){
// super();
// Timeout timeout=new Timeout(4, TimeUnit.SECONDS);
// try {
// httpProducer=Await.result(getContext().actorSelection("akka.tcp://app@host:port/user/actorAName").resolveOne(timeout), timeout.duration());
// } catch (Exception e) {
// Logger.error("Error fetching the routerHTTProducer");
// }
//}
@Override
public void onReceive(Object m) throws Exception {
if (m instanceof ActorIdentity) {
ActorIdentity identity = (ActorIdentity) m;
if (identity.correlationId().equals(ID) && identity.getRef() != null) {
actorA= identity.getRef();
}
}
//else if (m instanceof ...){}
}
}
Upvotes: 2
Reputation: 16412
Your solution looks fine and is a common thing to do. Akka references designed to be location transparent and serializable. Thus you can send Actor references to remote clients and they'll just use them without any additional setup.
Upvotes: 4