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);