Fix exceptions when enabling gossip on nodes that haven't joined the ring

Patch by Dikang Gu; reviewed by Joel Knighton for CASSANDRA-12253


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/df819ec8
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/df819ec8
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/df819ec8

Branch: refs/heads/trunk
Commit: df819ec8334c7a215f8d409804186a8106e91097
Parents: 50726e7
Author: Joel Knighton <joel.knigh...@datastax.com>
Authored: Thu Sep 15 17:11:10 2016 -0500
Committer: Aleksey Yeschenko <alek...@apache.org>
Committed: Wed Sep 21 18:13:28 2016 -0700

----------------------------------------------------------------------
 CHANGES.txt                                        |  1 +
 src/java/org/apache/cassandra/gms/Gossiper.java    |  4 ++--
 .../apache/cassandra/service/StorageService.java   | 17 ++++++++++++++---
 3 files changed, 17 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/df819ec8/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ee4015e..bc9fc5b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.8
+ * Fix exceptions when enabling gossip on nodes that haven't joined the ring 
(CASSANDRA-12253)
  * Fix authentication problem when invoking clqsh copy from a SOURCE command 
(CASSANDRA-12642)
  * Decrement pending range calculator jobs counter in finally block
   (CASSANDRA-12554)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/df819ec8/src/java/org/apache/cassandra/gms/Gossiper.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/gms/Gossiper.java 
b/src/java/org/apache/cassandra/gms/Gossiper.java
index a8f9524..06b14c4 100644
--- a/src/java/org/apache/cassandra/gms/Gossiper.java
+++ b/src/java/org/apache/cassandra/gms/Gossiper.java
@@ -1446,7 +1446,7 @@ public class Gossiper implements 
IFailureDetectionEventListener, GossiperMBean
     public void stop()
     {
         EndpointState mystate = 
endpointStateMap.get(FBUtilities.getBroadcastAddress());
-        if (mystate != null && !isSilentShutdownState(mystate))
+        if (mystate != null && !isSilentShutdownState(mystate) && 
StorageService.instance.isJoined())
         {
             logger.info("Announcing shutdown");
             addLocalApplicationState(ApplicationState.STATUS, 
StorageService.instance.valueFactory.shutdown(true));
@@ -1456,7 +1456,7 @@ public class Gossiper implements 
IFailureDetectionEventListener, GossiperMBean
             
Uninterruptibles.sleepUninterruptibly(Integer.getInteger("cassandra.shutdown_announce_in_ms",
 2000), TimeUnit.MILLISECONDS);
         }
         else
-            logger.warn("No local state or state is in silent shutdown, not 
announcing shutdown");
+            logger.warn("No local state, state is in silent shutdown, or node 
hasn't joined, not announcing shutdown");
         if (scheduledGossipTask != null)
             scheduledGossipTask.cancel(false);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/df819ec8/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java 
b/src/java/org/apache/cassandra/service/StorageService.java
index 9197ab1..0b6e851 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -185,6 +185,7 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
     // true when keeping strict consistency while bootstrapping
     private boolean useStrictConsistency = 
Boolean.parseBoolean(System.getProperty("cassandra.consistent.rangemovement", 
"true"));
     private static final boolean allowSimultaneousMoves = 
Boolean.valueOf(System.getProperty("cassandra.consistent.simultaneousmoves.allow","false"));
+    private static final boolean joinRing = 
Boolean.parseBoolean(System.getProperty("cassandra.join_ring", "true"));
     private boolean replacing;
     private UUID replacingId;
 
@@ -292,7 +293,17 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
         if (!initialized)
         {
             logger.warn("Starting gossip by operator request");
-            setGossipTokens(getLocalTokens());
+            Collection<Token> tokens = SystemKeyspace.getSavedTokens();
+
+            boolean validTokens = tokens != null && !tokens.isEmpty();
+
+            // shouldn't be called before these are set if we intend to join 
the ring/are in the process of doing so
+            if (joined || joinRing)
+                assert validTokens : "Cannot start gossiping for a node 
intended to join without valid tokens";
+
+            if (validTokens)
+                setGossipTokens(tokens);
+
             Gossiper.instance.forceNewerGeneration();
             Gossiper.instance.start((int) (System.currentTimeMillis() / 1000));
             initialized = true;
@@ -631,7 +642,7 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
             logger.warn("Error loading counter cache", t);
         }
 
-        if (Boolean.parseBoolean(System.getProperty("cassandra.join_ring", 
"true")))
+        if (joinRing)
         {
             joinTokenRing(delay);
         }
@@ -674,7 +685,7 @@ public class StorageService extends 
NotificationBroadcasterSupport implements IE
         {
             Map<ApplicationState, VersionedValue> appStates = new 
EnumMap<>(ApplicationState.class);
 
-            if (replacing && 
!(Boolean.parseBoolean(System.getProperty("cassandra.join_ring", "true"))))
+            if (replacing && !joinRing)
                 throw new ConfigurationException("Cannot set both 
join_ring=false and attempt to replace a node");
             if (DatabaseDescriptor.getReplaceTokens().size() > 0 || 
DatabaseDescriptor.getReplaceNode() != null)
                 throw new RuntimeException("Replace method removed; use 
cassandra.replace_address instead");

Reply via email to