Class SwimGossipProtocol

java.lang.Object
com.loomcache.server.cluster.SwimGossipProtocol
All Implemented Interfaces:
AutoCloseable

public class SwimGossipProtocol extends Object implements AutoCloseable
Scalable Weakly-consistent Infection-style Membership (SWIM) protocol detector.

Implements the SWIM gossip protocol as described in "SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol" (Das et al., 2002).

Key features:

  • Scalable membership detection with O(log N) load per node
  • Infection-style dissemination of membership updates
  • Suspicion mechanism with timeout-based confirmation
  • Incarnation numbers for refuting false suspicions
  • Protocol period with ping, ping-req, suspect, alive, and dead states
  • Thread-safe with virtual thread support via locked operations

The protocol operates in rounds: each round, the local node selects a random member and sends a ping. If no ack is received within the timeout, it sends ping-req messages to k random members. After the suspicion timeout, a suspected member transitions to dead.

See Also:
  • Constructor Details

    • SwimGossipProtocol

      public SwimGossipProtocol(String localNodeId, String localAddress, int localPort, long protocolPeriodMs, long suspicionTimeoutMs, int pingReqFanout, int initialDisseminationCount, @Nullable io.micrometer.core.instrument.MeterRegistry meterRegistry)
      Create a SWIM gossip protocol detector with custom configuration.
      Parameters:
      localNodeId - unique identifier for this node
      localAddress - network address of this node
      localPort - network port for SWIM protocol
      protocolPeriodMs - protocol round duration in milliseconds
      suspicionTimeoutMs - suspicion timeout in milliseconds
      pingReqFanout - number of members to send ping-req to
      initialDisseminationCount - initial dissemination count for messages
      meterRegistry - optional MeterRegistry for metrics
    • SwimGossipProtocol

      public SwimGossipProtocol(String localNodeId, String localAddress, int localPort)
      Create a SWIM gossip protocol detector with default configuration.
      Parameters:
      localNodeId - unique identifier for this node
      localAddress - network address of this node
      localPort - network port for SWIM protocol
    • SwimGossipProtocol

      public SwimGossipProtocol(String localNodeId, String localAddress, int localPort, io.micrometer.core.instrument.MeterRegistry meterRegistry)
      Create a SWIM gossip protocol detector with metrics support.
      Parameters:
      localNodeId - unique identifier for this node
      localAddress - network address of this node
      localPort - network port for SWIM protocol
      meterRegistry - MeterRegistry for metrics
  • Method Details

    • addMember

      public SwimGossipProtocol.MemberInfo addMember(String nodeId, String address, int port)
      Add or update a member in the cluster.
      Parameters:
      nodeId - unique identifier for the member
      address - network address of the member
      port - network port for SWIM protocol
      Returns:
      the new MemberInfo
    • getMember

      public @Nullable SwimGossipProtocol.MemberInfo getMember(String nodeId)
      Get a member by node ID.
      Parameters:
      nodeId - the member's node ID
      Returns:
      the MemberInfo, or null if not found
    • getAllMembers

      public Collection<SwimGossipProtocol.MemberInfo> getAllMembers()
      Get all members.
      Returns:
      collection of all members
    • getAliveMembers

      public Collection<SwimGossipProtocol.MemberInfo> getAliveMembers()
      Get all alive members.
      Returns:
      collection of alive members
    • getSuspectedMembers

      public Collection<SwimGossipProtocol.MemberInfo> getSuspectedMembers()
      Get all suspected members.
      Returns:
      collection of suspected members
    • getDeadMembers

      public Collection<SwimGossipProtocol.MemberInfo> getDeadMembers()
      Get all dead members.
      Returns:
      collection of dead members
    • removeMember

      public boolean removeMember(String nodeId)
      Remove a member from the cluster.
      Parameters:
      nodeId - the member's node ID
      Returns:
      true if the member was removed, false if not found
    • handlePing

      public void handlePing(String fromNodeId, String fromAddress, int fromPort, long fromIncarnation)
      Handle a ping message from another node (membership update).
      Parameters:
      fromNodeId - the sender's node ID
      fromAddress - the sender's address
      fromPort - the sender's port
      fromIncarnation - the sender's incarnation number
    • handleSuspect

      public void handleSuspect(String suspectedNodeId, long incarnation, long sourcePriority)
      Handle a suspected member notification (from gossip).
      Parameters:
      suspectedNodeId - the suspected member's node ID
      incarnation - the incarnation number
      sourcePriority - incarnation number of the suspecting member (for conflict resolution)
    • handleAlive

      public void handleAlive(String nodeId, String address, int port, long incarnation)
      Handle an alive notification (refutes suspicion).
      Parameters:
      nodeId - the member's node ID
      address - the member's address
      port - the member's port
      incarnation - the member's incarnation number
    • handleDead

      public void handleDead(String nodeId, long incarnation)
      Handle a dead notification.
      Parameters:
      nodeId - the dead member's node ID
      incarnation - the incarnation number
    • incrementIncarnation

      public void incrementIncarnation()
      Increment local incarnation number (refute suspicions against self).
    • getIncarnationNumber

      public long getIncarnationNumber()
      Get the local incarnation number.
      Returns:
      the current local incarnation
    • selectRandomAliveMembers

      protected List<SwimGossipProtocol.MemberInfo> selectRandomAliveMembers(int fanout, @Nullable String exclude)
      Select k random alive members (excluding self and optionally another member).
      Parameters:
      fanout - number of members to select
      exclude - optional member ID to exclude
      Returns:
      list of selected members
    • start

      public void start()
      Start the protocol ticker thread. This should be called before the protocol is used.
    • stop

      public void stop()
      Stop the protocol ticker thread.
    • executeProtocolRound

      protected void executeProtocolRound()
      Execute one protocol round. 1. Select a random alive member 2. Check for suspected members whose timeout has expired
    • selectProbeTarget

      protected SwimGossipProtocol.MemberInfo selectProbeTarget(List<SwimGossipProtocol.MemberInfo> aliveMembers)
    • getProtocolRoundCount

      public long getProtocolRoundCount()
      Get the protocol round count.
      Returns:
      number of protocol rounds executed
    • setDirectPingProbe

      public void setDirectPingProbe(SwimGossipProtocol.DirectPingProbe directPingProbe)
    • clearDirectPingProbe

      public void clearDirectPingProbe()
    • setIndirectPingProbe

      public void setIndirectPingProbe(SwimGossipProtocol.IndirectPingProbe indirectPingProbe)
    • clearIndirectPingProbe

      public void clearIndirectPingProbe()
    • close

      public void close()
      Close and stop the protocol.
      Specified by:
      close in interface AutoCloseable
    • toString

      public String toString()
      Overrides:
      toString in class Object