This is an automated email from the ASF dual-hosted git repository. benedict pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit ce2a0a28bc9ca21e1fae29f2a38448a877db06c3 Author: Benedict Elliott Smith <bened...@apache.org> AuthorDate: Mon Apr 26 12:09:20 2021 +0100 [CASSANDRA-16932] CEP-10 Phase 2: Minor Gossip Fixes * Ensure we apply new states in correct order so as not to lose TOKEN message * Permit replacement nodes to join the ring with lower heartbeat state than node being replaced --- src/java/org/apache/cassandra/gms/Gossiper.java | 23 +++++++++++++++++++++- .../apache/cassandra/service/StorageService.java | 4 +++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/cassandra/gms/Gossiper.java b/src/java/org/apache/cassandra/gms/Gossiper.java index 3219145..e2ebedc 100644 --- a/src/java/org/apache/cassandra/gms/Gossiper.java +++ b/src/java/org/apache/cassandra/gms/Gossiper.java @@ -1587,12 +1587,33 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean if (!hasMajorVersion3Nodes()) localState.removeMajorVersion3LegacyApplicationStates(); + // need to run STATUS or STATUS_WITH_PORT first to handle BOOT_REPLACE correctly (else won't be a member, so TOKENS won't be processed) for (Entry<ApplicationState, VersionedValue> updatedEntry : updatedStates) { + switch (updatedEntry.getKey()) + { + default: + continue; + case STATUS: + if (localState.containsApplicationState(ApplicationState.STATUS_WITH_PORT)) + continue; + case STATUS_WITH_PORT: + } + doOnChangeNotifications(addr, updatedEntry.getKey(), updatedEntry.getValue()); + } + + for (Entry<ApplicationState, VersionedValue> updatedEntry : updatedStates) + { + switch (updatedEntry.getKey()) + { + // We should have alredy handled these two states above: + case STATUS_WITH_PORT: + case STATUS: + continue; + } // filters out legacy change notifications // only if local state already indicates that the peer has the new fields if ((ApplicationState.INTERNAL_IP == updatedEntry.getKey() && localState.containsApplicationState(ApplicationState.INTERNAL_ADDRESS_AND_PORT)) - ||(ApplicationState.STATUS == updatedEntry.getKey() && localState.containsApplicationState(ApplicationState.STATUS_WITH_PORT)) || (ApplicationState.RPC_ADDRESS == updatedEntry.getKey() && localState.containsApplicationState(ApplicationState.NATIVE_ADDRESS_AND_PORT))) continue; doOnChangeNotifications(addr, updatedEntry.getKey(), updatedEntry.getValue()); diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index 1638505..5c0f4bb 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -2728,7 +2728,9 @@ public class StorageService extends NotificationBroadcasterSupport implements IE tokensToUpdateInMetadata.add(token); tokensToUpdateInSystemKeyspace.add(token); } - else if (Gossiper.instance.compareEndpointStartup(endpoint, currentOwner) > 0) + // Note: in test scenarios, there may not be any delta between the heartbeat generations of the old + // and new nodes, so we first check whether the new endpoint is marked as a replacement for the old. + else if (endpoint.equals(tokenMetadata.getReplacementNode(currentOwner).orElse(null)) || Gossiper.instance.compareEndpointStartup(endpoint, currentOwner) > 0) { tokensToUpdateInMetadata.add(token); tokensToUpdateInSystemKeyspace.add(token); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org