Question

I have a number of concurrent clients - i.e. threads running and doing something concurrently. Each client implements a listener of some event bus. A message from that bus can arrive to one or more clients. My task is to broadcast that message to all the clients.

This task seems simple, but I cannot find a solution which is not ugly in some way.

(1) The straightforward solution:

void onMessageArrived(Message message) {
   broadcast(message);
}
  • is bad because each message will be broadcasted for many times because several clients can receive that message, and thus several onMessageArrived handlers can run.

(2) We can store the broadcasted messages in some list:

void onMessageArrived(Message message) {
 if (alreadyBroadcastedConcurrentMap.putIfAbsent(message)==null) {
     broadcast(message);
 }
}
  • this solves the previously mentioned problem, but many clients will repeat the useless operation of putting the already existing message into that list.

But may be there are some better options?

Java.

Was it helpful?

Solution

Your design contains flaws, or it is badly explained. Either you want to broadcast to all clients, or multicast to a selected list. It doesn't make sense to specify some recipients and then make each recipient responsible for delivering it to all the other clients, handling duplications and races by hand. Just make all clients listening to the bus, possibly ignoring messages.

I'd introduce a new central Broadcaster

public class Broadcaster {

  List<Client> clients;

  public void broadcast(Message msg) {
    for (Client client: clients)
      if (!msg.from().equals(client))
        msg.send(client);
  }
}

Obviously each client will have to register to this broadcast domain

public class Client {

  private Broadcaster broadcaster;

  public void join(Broadcaster broadcaster) {
    this.broadcaster = broadcaster;
    broadcaster.announce(this);
  }

}

and just forget about multiple delivery. You can go further and simulate a LAN by using multiple broadcast domains, if the number of clients is huge and you have other very strict requirements - which I don't think you have

OTHER TIPS

The problem lies with the fact that you receive multiple messages in the first place. In theory, if you should get 5 requests to broadcast, then 5 broadcasts should take place by the way your event system works. Simply put, if that is not what you want, then you should not use this pattern.

If receiving multiple messages is not something you can control, then at the least, the receiver passing messages should note repeated messages and disregard them rather than passing them onto other threads.

In short, the thread only does what it is told. It should not have to worry about the state of another thread, so you should either switch patterns or intercept the message prior to passing it on to your threads.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top