You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2010/10/05 00:06:31 UTC

svn commit: r1004453 - in /cassandra/trunk: CHANGES.txt src/java/org/apache/cassandra/dht/BootStrapper.java src/java/org/apache/cassandra/service/StorageService.java

Author: jbellis
Date: Mon Oct  4 22:06:31 2010
New Revision: 1004453

URL: http://svn.apache.org/viewvc?rev=1004453&view=rev
Log:
fix moving nodes with no keyspaces defined
patch by Nick Bailey and jbellis for CASSANDRA-1574

Modified:
    cassandra/trunk/CHANGES.txt
    cassandra/trunk/src/java/org/apache/cassandra/dht/BootStrapper.java
    cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java

Modified: cassandra/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1004453&r1=1004452&r2=1004453&view=diff
==============================================================================
--- cassandra/trunk/CHANGES.txt (original)
+++ cassandra/trunk/CHANGES.txt Mon Oct  4 22:06:31 2010
@@ -8,6 +8,7 @@ dev
  * lock row cache updates to prevent race condition (CASSANDRA-1293)
  * remove assertion causing rare (and harmless) error messages in
    commitlog (CASSANDRA-1330)
+ * fix moving nodes with no keyspaces defined (CASSANDRA-1574)
 
 
 0.7-beta2

Modified: cassandra/trunk/src/java/org/apache/cassandra/dht/BootStrapper.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/dht/BootStrapper.java?rev=1004453&r1=1004452&r2=1004453&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/dht/BootStrapper.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/dht/BootStrapper.java Mon Oct  4 22:06:31 2010
@@ -23,6 +23,7 @@ package org.apache.cassandra.dht;
  import java.net.InetAddress;
  import java.util.*;
  import java.util.concurrent.locks.Condition;
+ import java.util.concurrent.CountDownLatch;
 
  import com.google.common.collect.ArrayListMultimap;
  import com.google.common.collect.HashMultimap;
@@ -67,50 +68,57 @@ public class BootStrapper
         tokenMetadata = tmd;
     }
 
-    public void startBootstrap() throws IOException
+    public void bootstrap() throws IOException
     {
         if (logger.isDebugEnabled())
             logger.debug("Beginning bootstrap process");
 
-        final Multimap<InetAddress, String> bootstrapNodes = HashMultimap.create();
         final Multimap<String, Map.Entry<InetAddress, Collection<Range>>> rangesToFetch = HashMultimap.create();
 
+        int requests = 0;
         for (String table : DatabaseDescriptor.getNonSystemTables())
         {
             Map<InetAddress, Collection<Range>> workMap = getWorkMap(getRangesWithSources(table)).asMap();
             for (Map.Entry<InetAddress, Collection<Range>> entry : workMap.entrySet())
             {
-                bootstrapNodes.put(entry.getKey(), table);
+                requests++;
                 rangesToFetch.put(table, entry);
             }
         }
 
+        final CountDownLatch latch = new CountDownLatch(requests);
         for (final String table : rangesToFetch.keySet())
         {
             /* Send messages to respective folks to stream data over to me */
             for (Map.Entry<InetAddress, Collection<Range>> entry : rangesToFetch.get(table))
             {
                 final InetAddress source = entry.getKey();
+                Collection<Range> ranges = entry.getValue();
                 final Runnable callback = new Runnable()
                 {
                     public void run()
                     {
-                        synchronized (bootstrapNodes)
-                        {
-                            bootstrapNodes.remove(source, table);
-                            if (logger.isDebugEnabled())
-                                logger.debug(String.format("Removed %s/%s as a bootstrap source; remaining is [%s]",
-                                                           source, table, StringUtils.join(bootstrapNodes.keySet(), ", ")));
-                            if (bootstrapNodes.isEmpty())
-                                StorageService.instance.finishBootstrapping();
-                        }
+                        latch.countDown();
+                        if (logger.isDebugEnabled())
+                            logger.debug(String.format("Removed %s/%s as a bootstrap source; remaining is %s",
+                                                       source, table, latch.getCount()));
                     }
                 };
                 if (logger.isDebugEnabled())
-                    logger.debug("Bootstrapping from " + source + " ranges " + StringUtils.join(entry.getValue(), ", "));
-                StreamIn.requestRanges(source, table, entry.getValue(), callback);
+                    logger.debug("Bootstrapping from " + source + " ranges " + StringUtils.join(ranges, ", "));
+                StreamIn.requestRanges(source, table, ranges, callback);
             }
         }
+
+        try
+        {
+            latch.await();
+            StorageService.instance.finishBootstrapping();
+        }
+        catch (InterruptedException e)
+        {
+            throw new AssertionError(e);
+        }
     }
 
     /**

Modified: cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java?rev=1004453&r1=1004452&r2=1004453&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java Mon Oct  4 22:06:31 2010
@@ -394,7 +394,10 @@ public class StorageService implements I
             Token token = BootStrapper.getBootstrapToken(tokenMetadata_, StorageLoadBalancer.instance.getLoadInfo());
             // don't bootstrap if there are no tables defined.
             if (DatabaseDescriptor.getNonSystemTables().size() > 0)
-                startBootstrap(token);
+            {
+                bootstrap(token);
+                assert !isBootstrapMode; // bootstrap will block until finishec
+            }
             else
             {
                 isBootstrapMode = false;
@@ -403,18 +406,6 @@ public class StorageService implements I
                 Gossiper.instance.addLocalApplicationState(ApplicationState.STATUS, valueFactory.normal(token));
                 setMode("Normal", false);
             }
-            // don't finish startup (enabling thrift) until after bootstrap is done
-            while (isBootstrapMode)
-            {
-                try
-                {
-                    Thread.sleep(100);
-                }
-                catch (InterruptedException e)
-                {
-                    throw new AssertionError(e);
-                }
-            }
         }
         else
         {
@@ -457,7 +448,7 @@ public class StorageService implements I
             logger_.info(m);
     }
 
-    private void startBootstrap(Token token) throws IOException
+    private void bootstrap(Token token) throws IOException
     {
         isBootstrapMode = true;
         SystemTable.updateToken(token); // DON'T use setToken, that makes us part of the ring locally which is incorrect until we are done bootstrapping
@@ -472,7 +463,7 @@ public class StorageService implements I
             throw new AssertionError(e);
         }
         setMode("Bootstrapping", true);
-        new BootStrapper(FBUtilities.getLocalAddress(), token, tokenMetadata_).startBootstrap(); // handles token update
+        new BootStrapper(FBUtilities.getLocalAddress(), token, tokenMetadata_).bootstrap(); // handles token update
     }
 
     public boolean isBootstrapMode()
@@ -1710,7 +1701,7 @@ public class StorageService implements I
                     bootstrapToken = BootStrapper.getBalancedToken(tokenMetadata_, StorageLoadBalancer.instance.getLoadInfo());
                 }
                 logger_.info("re-bootstrapping to new token {}", bootstrapToken);
-                startBootstrap(bootstrapToken);
+                bootstrap(bootstrapToken);
             }
         };
         unbootstrap(finishMoving);