Author: jbellis
Date: Fri Dec 18 16:13:53 2009
New Revision: 892294

URL: http://svn.apache.org/viewvc?rev=892294&view=rev
Log:
Include dead nodes in gossip to avoid a variety of problems.  patch by Jaakko 
Laine; reviewed by jbellis for CASSANDRA-634

Modified:
    incubator/cassandra/branches/cassandra-0.5/CHANGES.txt
    
incubator/cassandra/branches/cassandra-0.5/src/java/org/apache/cassandra/gms/Gossiper.java

Modified: incubator/cassandra/branches/cassandra-0.5/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.5/CHANGES.txt?rev=892294&r1=892293&r2=892294&view=diff
==============================================================================
--- incubator/cassandra/branches/cassandra-0.5/CHANGES.txt (original)
+++ incubator/cassandra/branches/cassandra-0.5/CHANGES.txt Fri Dec 18 16:13:53 
2009
@@ -7,6 +7,8 @@
  * Fix anti-entropy assertion error (CASSANDRA-639)
  * Fix pending range conflicts when bootstapping or moving
    multiple nodes at once (CASSANDRA-603)
+ * Include dead nodes in gossip to avoid a variety of problems
+   (CASSANDRA-634)
 
 
 0.5.0 beta 2

Modified: 
incubator/cassandra/branches/cassandra-0.5/src/java/org/apache/cassandra/gms/Gossiper.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.5/src/java/org/apache/cassandra/gms/Gossiper.java?rev=892294&r1=892293&r2=892294&view=diff
==============================================================================
--- 
incubator/cassandra/branches/cassandra-0.5/src/java/org/apache/cassandra/gms/Gossiper.java
 (original)
+++ 
incubator/cassandra/branches/cassandra-0.5/src/java/org/apache/cassandra/gms/Gossiper.java
 Fri Dec 18 16:13:53 2009
@@ -241,20 +241,20 @@
         int maxVersion = getMaxEndPointStateVersion(epState);
         gDigests.add( new GossipDigest(localEndPoint_, generation, maxVersion) 
);
 
-        List<InetAddress> endpoints = new ArrayList<InetAddress>( 
liveEndpoints_ );
+        List<InetAddress> endpoints = new 
ArrayList<InetAddress>(endPointStateMap_.keySet());
         Collections.shuffle(endpoints, random_);
-        for ( InetAddress liveEndPoint : endpoints )
+        for (InetAddress endPoint : endpoints)
         {
-            epState = endPointStateMap_.get(liveEndPoint);
-            if ( epState != null )
+            epState = endPointStateMap_.get(endPoint);
+            if (epState != null)
             {
                 generation = epState.getHeartBeatState().getGeneration();
                 maxVersion = getMaxEndPointStateVersion(epState);
-                gDigests.add( new GossipDigest(liveEndPoint, generation, 
maxVersion) );
+                gDigests.add(new GossipDigest(endPoint, generation, 
maxVersion));
             }
             else
             {
-               gDigests.add( new GossipDigest(liveEndPoint, 0, 0) );
+               gDigests.add(new GossipDigest(endPoint, 0, 0));
             }
         }
 
@@ -541,13 +541,33 @@
 
     private void handleNewJoin(InetAddress ep, EndPointState epState)
     {
-       logger_.info("Node " + ep + " has now joined.");
+       logger_.info("Node " + ep + " is now part of the cluster");
+        handleMajorStateChange(ep, epState, false);
+    }
+
+    private void handleGenerationChange(InetAddress ep, EndPointState epState)
+    {
+        logger_.info("Node " + ep + " has restarted, now UP again");
+        handleMajorStateChange(ep, epState, true);
+    }
+
+    /**
+     * This method is called whenever there is a "big" change in ep state 
(either a previously
+     * unknown node or a generation change for a known node). If the node is 
new, it will be
+     * initially marked as dead. It will be marked alive as soon as another 
piece of gossip
+     * arrives. On the other hand if the node is already known (generation 
change), we will
+     * immediately mark it alive.
+     *
+     * @param ep endpoint
+     * @param epState EndPointState for the endpoint
+     * @param isKnownNode is this node familiar to us already (present in 
endPointStateMap)
+     */
+    private void handleMajorStateChange(InetAddress ep, EndPointState epState, 
boolean isKnownNode)
+    {
         endPointStateMap_.put(ep, epState);
-        isAlive(ep, epState, true);
+        isAlive(ep, epState, isKnownNode);
         for (IEndPointStateChangeSubscriber subscriber : subscribers_)
-        {
             subscriber.onJoin(ep, epState);
-        }
     }
 
     synchronized void applyStateLocally(Map<InetAddress, EndPointState> 
epStateMap)
@@ -571,7 +591,7 @@
 
                if (remoteGeneration > localGeneration)
                {
-                       handleNewJoin(ep, remoteState);
+                    handleGenerationChange(ep, remoteState);
                }
                else if ( remoteGeneration == localGeneration )
                {
@@ -601,7 +621,6 @@
 
         if ( remoteHbState.getGeneration() > localHbState.getGeneration() )
         {
-            markAlive(addr, localState);
             localState.setHeartBeatState(remoteHbState);
         }
         if ( localHbState.getGeneration() == remoteHbState.getGeneration() )


Reply via email to