oustriem
oustriem

Reputation: 88

Akka ActorSelection over a whole cluser

I have a simple cluster with a service actor named "service" on each node. This service is respectively exposed with ClusterClientRecptionist to be able to use ist from outside the cluster with ClusterClient.

A client then registers users, which are created on random nodes of the cluster (because the ClusterClient dispatches randomly). For example /user/service/user1 on node1 and /user/service/user2 on node2.

What I want to do now, is to send a message to all registered users, independently of their physical location. I thout that was easy by using an ActorSelection like /user/service/*. But this only resolves local acotrs on the corresponding node.

I work with Java by the way.

Upvotes: 1

Views: 332

Answers (1)

oustriem
oustriem

Reputation: 88

Option 1

I just solved it by using the DistributedPubSubMediator as described in this question and documented here.

private ActorRef mediator = DistributedPubSub.get(getContext().system()).mediator();

@Override
public void onReceive(Object msg) throws Exception {
    String msgStr = msg.toString();
    String val = msgStr.substring(4);
    if (msgStr.startsWith("add")) {
        ActorRef act = context().actorOf(Props.create(User.class, val), val);
        // subscribe the newly created user on topic "allUsers"
        mediator.tell(new DistributedPubSubMediator.Subscribe("allUsers", act), self());
        System.out.println("user created: " + act);
    } else if (msgStr.startsWith("say")) {
        // broadcast text message to all subscribed users
        mediator.tell(new DistributedPubSubMediator.Publish("allUsers", new Text(val)), self());
    }
}

Option 2

A second successful option is by using a BroadcastGroup router. Important is that the clustering is enabled in configuration:

akka.actor.deployment {
  /allUsers {
    router = broadcast-group
    routees.paths = ["/user/service/*"]
    cluster {
      enabled = on
      allow-local-routees = on
    }
  }
}

Afterwards, it can be used straightforward as documented.

ActorRef allUsers = system.actorOf(FromConfig.getInstance().props(), "allUsers");
[...]
allUsers.tell(new Text(val), self());

Upvotes: 1

Related Questions