Node does not send multiple inflight echos

patch by Cameron Zemek; reviewed by Stefan Miklosovic, Brandon Williams for CASSANDRA-18866
This commit is contained in:
Stefan Miklosovic 2026-03-04 09:07:17 +01:00
parent ee635f5c45
commit 3ad4794aa0
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
2 changed files with 24 additions and 7 deletions

View File

@ -1,4 +1,5 @@
4.0.20
* Node does not send multiple inflight echos (CASSANDRA-18866)
* Obsolete expired SSTables before compaction starts (CASSANDRA-19776)
* No need to evict already prepared statements, as it creates a race condition between multiple threads (CASSANDRA-17401)
* Switch lz4-java to at.yawk.lz4 version due to CVE (CASSANDRA-21052)

View File

@ -140,6 +140,9 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
@VisibleForTesting
final Set<InetAddressAndPort> liveEndpoints = new ConcurrentSkipListSet<>();
/* Inflight echo requests. */
private final Map<InetAddressAndPort, EndpointState> inflightEcho = new ConcurrentHashMap<>();
/* unreachable member set */
private final Map<InetAddressAndPort, Long> unreachableEndpoints = new ConcurrentHashMap<>();
@ -180,6 +183,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
{
unreachableEndpoints.clear();
liveEndpoints.clear();
inflightEcho.clear();
justRemovedEndpoints.clear();
expireTimeEndpointMap.clear();
endpointStateMap.clear();
@ -659,6 +663,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
}
liveEndpoints.remove(endpoint);
inflightEcho.remove(endpoint);
unreachableEndpoints.remove(endpoint);
MessagingService.instance().versions.reset(endpoint);
quarantineEndpoint(endpoint);
@ -1328,14 +1333,24 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
{
localState.markDead();
Message<NoPayload> echoMessage = Message.out(ECHO_REQ, noPayload);
logger.trace("Sending ECHO_REQ to {}", addr);
RequestCallback echoHandler = msg ->
EndpointState prevState = inflightEcho.put(addr, localState);
boolean sendEcho = !localState.equals(prevState);
if (sendEcho)
{
runInGossipStageBlocking(() -> realMarkAlive(addr, localState));
};
MessagingService.instance().sendWithCallback(echoMessage, addr, echoHandler);
Message<NoPayload> echoMessage = Message.out(ECHO_REQ, noPayload);
logger.trace("Sending ECHO_REQ to {}", addr);
RequestCallback echoHandler = msg ->
{
runInGossipStageBlocking(() -> {
EndpointState epState = inflightEcho.remove(addr);
if (epState != null)
realMarkAlive(addr, epState);
});
};
MessagingService.instance().sendWithCallback(echoMessage, addr, echoHandler);
}
else
logger.trace("Skipping ECHO_REQ to {} since it is already inflight", addr);
GossiperDiagnostics.markedAlive(this, addr, localState);
}
@ -1386,6 +1401,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
{
localState.markDead();
liveEndpoints.remove(addr);
inflightEcho.remove(addr);
unreachableEndpoints.put(addr, System.nanoTime());
}