diff --git a/src/java/org/apache/cassandra/io/SSTable.java b/src/java/org/apache/cassandra/io/SSTable.java index 402c779b39..4f60c3773b 100644 --- a/src/java/org/apache/cassandra/io/SSTable.java +++ b/src/java/org/apache/cassandra/io/SSTable.java @@ -132,7 +132,8 @@ public abstract class SSTable /** @return full paths to all the files associated w/ this SSTable */ public List getAllFilenames() { - return Arrays.asList(getFilename(), indexFilename(), filterFilename()); + // TODO streaming relies on the -Data (getFilename) file to be last, this is clunky + return Arrays.asList(indexFilename(), filterFilename(), getFilename()); } public String getColumnFamilyName() diff --git a/src/java/org/apache/cassandra/io/Streaming.java b/src/java/org/apache/cassandra/io/Streaming.java index 3e16569072..4ddb1a51ab 100644 --- a/src/java/org/apache/cassandra/io/Streaming.java +++ b/src/java/org/apache/cassandra/io/Streaming.java @@ -83,9 +83,9 @@ public class Streaming { File file = new File(filename); streamContexts[i++] = new StreamContextManager.StreamContext(file.getAbsolutePath(), file.length(), table); - if (logger.isDebugEnabled()) - logger.debug("Stream context metadata " + streamContexts[i]); } + if (logger.isDebugEnabled()) + logger.debug("Stream context metadata " + StringUtils.join(streamContexts, ", ")); StreamManager.instance(target).addFilesToStream(streamContexts); StreamInitiateMessage biMessage = new StreamInitiateMessage(streamContexts); diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index f14ec18598..b745b7821d 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -169,13 +169,19 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto if (bootstrapSet.isEmpty()) { - isBootstrapMode = false; - SystemTable.setBootstrapped(); - Gossiper.instance().addApplicationState(StorageService.STATE_NORMAL, new ApplicationState(partitioner_.getTokenFactory().toString(getLocalToken()))); - logger_.info("Bootstrap completed! Now serving reads."); + finishBootstrapping(); } } + private void finishBootstrapping() + { + isBootstrapMode = false; + SystemTable.setBootstrapped(); + setToken(getLocalToken()); + Gossiper.instance().addApplicationState(StorageService.STATE_NORMAL, new ApplicationState(partitioner_.getTokenFactory().toString(getLocalToken()))); + logger_.info("Bootstrap completed! Now serving reads."); + } + private void updateForeignToken(Token token, InetAddress endpoint) { tokenMetadata_.update(token, endpoint); @@ -276,9 +282,22 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto logger_.info("Starting in bootstrap mode (first, sleeping to get load information)"); StorageLoadBalancer.instance().waitForLoadInfo(); logger_.info("... got load info"); - setToken(BootStrapper.getBootstrapToken(tokenMetadata_, StorageLoadBalancer.instance().getLoadInfo())); + Token token = BootStrapper.getBootstrapToken(tokenMetadata_, StorageLoadBalancer.instance().getLoadInfo()); + SystemTable.updateToken(token); // DON'T use setToken, that makes us part of the ring locally which is incorrect until we are done bootstrapping Gossiper.instance().addApplicationState(StorageService.STATE_BOOTSTRAPPING, new ApplicationState(partitioner_.getTokenFactory().toString(getLocalToken()))); new BootStrapper(replicationStrategy_, FBUtilities.getLocalAddress(), getLocalToken(), tokenMetadata_).startBootstrap(); // handles token update + // 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 { @@ -517,7 +536,7 @@ public final class StorageService implements IEndPointStateChangeSubscriber, Sto public Token getLocalToken() { - return tokenMetadata_.getToken(FBUtilities.getLocalAddress()); + return storageMetadata_.getToken(); } /* This methods belong to the MBean interface */