wibbleface
wibbleface

Reputation: 119

Sending messages between siblings in Java Akka

In Java, using Akka, I have a Main class which creates two actors (ActorA and ActorB). I can send messages from Main to the Actors, but how do I send messages between the two actors.

Main.java:

public class Main {

    public static void main(String[] args) {

        // Create the ‘actorTest’ actor system.
        final ActorSystem system = ActorSystem.create("actorTest");

        // Create the actors.
        ActorRef ActorRefA = system.actorOf(Props.create(ActorA.class));
        ActorRef ActorRefB = system.actorOf(Props.create(ActorB.class));

        // Send a message to ActorA.
        ActorRefA.tell("message A", ActorRefA);

     }

}

ActorA.java:

public class ActorA extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {
        System.out.println("ActorA received: " + message);

        // This is the line which I can't get to work:
        ActorRefB.tell("message B", self());

    }

}

As you've probably guessed I'm new to this, so any helpful links will be gratefully received. Thanks.

Upvotes: 2

Views: 1356

Answers (1)

nickebbitt
nickebbitt

Reputation: 1761

Assuming the actors both need to know about each other you have a couple of options that spring to mind:

  1. Inject the ActorRef of each actor into the other by passing a message from Main to each with the other's ActorRef
  2. Giving the ActorA and ActorB explicit names and sending a message to the other actor using their ActorPaths

Option 1

After creation of ActorA and ActorB in main, send the ActorRef of each to the other e.g.

public class Main {

public static void main(String[] args) {

    // Create the ‘actorTest’ actor system.
    final ActorSystem system = ActorSystem.create("actorTest");

    // Create the actors.
    ActorRef ActorRefA = system.actorOf(Props.create(ActorA.class));
    ActorRef ActorRefB = system.actorOf(Props.create(ActorB.class));

   // Inject ActorRefs
   ActorRefA.tell(ActorRefB, ActorRef.noSender());
   ActorRefB.tell(ActorRefA, ActorRef.noSender());

    // Send a message to ActorA.
    ActorRefA.tell("message A", ActorRefA);

 }

}

You will also need your ActorA and ActorB implementations to handle a message of this type e.g.

public class ActorA extends UntypedActor {

    private ActorRef actorRefB;

    @Override
    public void onReceive(Object message) throws Exception {
        System.out.println("ActorA received: " + message);

        if (message instanceof ActorRef) {
            actorRefB = message;
        } else if (message instanceof String) {
            // This is the line which I can't get to work:
            actorRefB.tell("message B", self());
        }

    }

}

You would obviously want more sophisticated checks on the variables and sequencing of events to prevent errors but hopefully you get the jist of it.

Option 2

If you name your actors explicitly on creation then you will be able to address them more reliably at their ActorPath using ActorSelection

Your Main class would become:

public class Main {

    public static void main(String[] args) {

        // Create the ‘actorTest’ actor system.
        final ActorSystem system = ActorSystem.create("actorTest");

        // Create the actors.
        ActorRef ActorRefA = system.actorOf(Props.create(ActorA.class), "actorA");
        ActorRef ActorRefB = system.actorOf(Props.create(ActorB.class), "actorB");

        // Send a message to ActorA.
        ActorRefA.tell("message A", ActorRefA);

     }

}

And then in your ActorA you would use the Actor Selection to address the other actor e.g.

public class ActorA extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {
        System.out.println("ActorA received: " + message);

        ActorSelection actorB = getContext().actorSelection("../actorB");
        actorB.tell("message B", self());

    }

}

It should be noted that there are no guarantees when using Actor Selection that the actor you're addressing actually exists. If you need that then see the following link for details of how to achieve it: http://doc.akka.io/docs/akka/2.4.2/java/untyped-actors.html#Identifying_Actors_via_Actor_Selection

Upvotes: 1

Related Questions