From 050942608e70d01e5833fe5d0e5019071f95c68b Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Fri, 15 Nov 2024 17:03:21 -0500 Subject: reliable multicast: announce presence to group --- src/main/java/derms/net/rmulticast/Announce.java | 47 ++++++++++++++++++++++ .../java/derms/net/rmulticast/AnnounceMessage.java | 10 +++++ .../java/derms/net/rmulticast/NullPayload.java | 10 +++++ src/main/java/derms/net/rmulticast/Receive.java | 7 +++- .../derms/net/rmulticast/ReliableMulticast.java | 7 ++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/main/java/derms/net/rmulticast/Announce.java create mode 100644 src/main/java/derms/net/rmulticast/AnnounceMessage.java create mode 100644 src/main/java/derms/net/rmulticast/NullPayload.java (limited to 'src/main/java/derms/net/rmulticast') diff --git a/src/main/java/derms/net/rmulticast/Announce.java b/src/main/java/derms/net/rmulticast/Announce.java new file mode 100644 index 0000000..08d817d --- /dev/null +++ b/src/main/java/derms/net/rmulticast/Announce.java @@ -0,0 +1,47 @@ +package derms.net.rmulticast; + +import derms.net.ConcurrentMulticastSocket; +import derms.net.Packet; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.time.Duration; +import java.util.logging.Logger; + +/** + * Periodically announce the presence of the local process to the group. + * Allows processes to populate their set of group members, even if not + * all members would normally send messages to the group. + */ +class Announce implements Runnable { + private static final Duration period = Duration.ofSeconds(30); + + private final DatagramPacket pkt; + private final ConcurrentMulticastSocket outSock; + private final Logger log; + + Announce(InetSocketAddress group, InetAddress laddr, ConcurrentMulticastSocket outSock) throws IOException { + AnnounceMessage msg = new AnnounceMessage(laddr); + this.pkt = Packet.encode(msg, group); + this.outSock = outSock; + this.log = Logger.getLogger(this.getClass().getName()); + } + + @Override + public void run() { + try { + for (;;) { + try { + Wait.forDuration(period); + outSock.send(pkt); + } catch (IOException e) { + log.warning(e.getMessage()); + } + } + } catch (InterruptedException e) { + log.info("Announce thread interrupted: " + e.getMessage()); + } + } +} diff --git a/src/main/java/derms/net/rmulticast/AnnounceMessage.java b/src/main/java/derms/net/rmulticast/AnnounceMessage.java new file mode 100644 index 0000000..bfe4b40 --- /dev/null +++ b/src/main/java/derms/net/rmulticast/AnnounceMessage.java @@ -0,0 +1,10 @@ +package derms.net.rmulticast; + +import java.net.InetAddress; + +/** A message whose only purpose is to announce the presence of the sender in the group. */ +class AnnounceMessage extends Message { + AnnounceMessage(InetAddress laddr) { + super(new NullPayload(), laddr, new MessageID[0], new MessageID[0]); + } +} diff --git a/src/main/java/derms/net/rmulticast/NullPayload.java b/src/main/java/derms/net/rmulticast/NullPayload.java new file mode 100644 index 0000000..1eee5d6 --- /dev/null +++ b/src/main/java/derms/net/rmulticast/NullPayload.java @@ -0,0 +1,10 @@ +package derms.net.rmulticast; + +import java.io.Serializable; + +class NullPayload implements Serializable, Hashable { + @Override + public int hash() { + return -1; + } +} diff --git a/src/main/java/derms/net/rmulticast/Receive.java b/src/main/java/derms/net/rmulticast/Receive.java index f20f833..29ee305 100644 --- a/src/main/java/derms/net/rmulticast/Receive.java +++ b/src/main/java/derms/net/rmulticast/Receive.java @@ -50,12 +50,15 @@ class Receive implements Runnable { } private void receive(Message msg) { + groupMembers.add(msg.sender); + + if (msg instanceof AnnounceMessage) + return; + acks.add(msg.id()); received.add(msg); delivered.add(msg); - groupMembers.add(msg.sender); - nacks.remove(msg.id()); retransmissions.remove(msg); diff --git a/src/main/java/derms/net/rmulticast/ReliableMulticast.java b/src/main/java/derms/net/rmulticast/ReliableMulticast.java index 528bb41..a9e1fa4 100644 --- a/src/main/java/derms/net/rmulticast/ReliableMulticast.java +++ b/src/main/java/derms/net/rmulticast/ReliableMulticast.java @@ -53,6 +53,13 @@ public class ReliableMulticast { (new Thread(new Retransmit(retransmissions, outSock, group))).start(); (new Thread(new Prune(received, groupMembers))).start(); + + try { + (new Thread(new Announce(group, laddr, outSock))).start(); + } catch (IOException e) { + log.severe("Failed to start announce thread: " + e.getMessage()); + throw e; + } } public void send(T payload) throws IOException { -- cgit v1.2.3