This is an automated email from the ASF dual-hosted git repository.

bdeggleston pushed a commit to branch cassandra-3.11
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit 01d6548e0dec465c01df4248e1d740c51710a36b
Merge: 839fc7e c3ce32e
Author: Blake Eggleston <bdeggles...@gmail.com>
AuthorDate: Thu Apr 25 10:21:22 2019 -0700

    Merge branch 'cassandra-3.0' into cassandra-3.11

 CHANGES.txt                                        |   1 +
 build.xml                                          |   1 +
 ide/idea/workspace.xml                             |   2 +-
 .../cassandra/config/DatabaseDescriptor.java       |   8 +
 src/java/org/apache/cassandra/gms/Gossiper.java    | 192 +++++++++++++++------
 .../apache/cassandra/service/StorageService.java   |  10 +-
 .../cassandra/distributed/impl/Instance.java       |  20 ++-
 .../org/apache/cassandra/gms/GossiperTest.java     |   1 +
 .../gms/PendingRangeCalculatorServiceTest.java     |   1 +
 .../cassandra/locator/CloudstackSnitchTest.java    |   1 +
 .../apache/cassandra/locator/EC2SnitchTest.java    |   1 +
 .../cassandra/locator/GoogleCloudSnitchTest.java   |   1 +
 .../cassandra/locator/PropertyFileSnitchTest.java  |   1 +
 13 files changed, 170 insertions(+), 70 deletions(-)

diff --cc CHANGES.txt
index 9ce2972,596d902..0506da7
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,9 -1,8 +1,10 @@@
 -3.0.19
 +3.11.5
 + * Fixed nodetool cfstats printing index name twice (CASSANDRA-14903)
 + * Add flag to disable SASI indexes, and warnings on creation 
(CASSANDRA-14866)
 +Merged from 3.0:
+  * Fix assorted gossip races and add related runtime checks (CASSANDRA-15059)
   * Fix mixed mode partition range scans with limit (CASSANDRA-15072)
   * cassandra-stress works with frozen collections: list and set 
(CASSANDRA-14907)
 - * For nodetool listsnapshots output, put spaces between columns, and 
increase snapshot padding (CASSANDRA-14876)
   * Fix handling FS errors on writing and reading flat files - LogTransaction 
and hints (CASSANDRA-15053)
   * Avoid double closing the iterator to avoid overcounting the number of 
requests (CASSANDRA-15058)
   * Improve `nodetool status -r` speed (CASSANDRA-14847)
diff --cc ide/idea/workspace.xml
index a7c991e,3424af3..8d1b0fc
--- a/ide/idea/workspace.xml
+++ b/ide/idea/workspace.xml
@@@ -167,7 -168,7 +167,7 @@@
        <option name="MAIN_CLASS_NAME" value="" />
        <option name="METHOD_NAME" value="" />
        <option name="TEST_OBJECT" value="class" />
-       <option name="VM_PARAMETERS" 
value="-Dcassandra.config=file://$PROJECT_DIR$/test/conf/cassandra.yaml 
-Dlogback.configurationFile=file://$PROJECT_DIR$/test/conf/logback-test.xml 
-Dcassandra.logdir=$PROJECT_DIR$/build/test/logs 
-Djava.library.path=$PROJECT_DIR$/lib/sigar-bin -ea -XX:MaxMetaspaceSize=256M 
-XX:SoftRefLRUPolicyMSPerMB=0" />
 -      <option name="VM_PARAMETERS" 
value="-Dcassandra.config=file://$PROJECT_DIR$/test/conf/cassandra.yaml 
-Dlogback.configurationFile=file://$PROJECT_DIR$/test/conf/logback-test.xml 
-Dcassandra.logdir=$PROJECT_DIR$/build/test/logs -ea -XX:MaxMetaspaceSize=256M 
-XX:SoftRefLRUPolicyMSPerMB=0 -Dcassandra.strict.runtime.checks=true" />
++      <option name="VM_PARAMETERS" 
value="-Dcassandra.config=file://$PROJECT_DIR$/test/conf/cassandra.yaml 
-Dlogback.configurationFile=file://$PROJECT_DIR$/test/conf/logback-test.xml 
-Dcassandra.logdir=$PROJECT_DIR$/build/test/logs 
-Djava.library.path=$PROJECT_DIR$/lib/sigar-bin -ea -XX:MaxMetaspaceSize=256M 
-XX:SoftRefLRUPolicyMSPerMB=0 -Dcassandra.strict.runtime.checks=true" />
        <option name="PARAMETERS" value="" />
        <option name="WORKING_DIRECTORY" value="" />
        <option name="ENV_VARIABLES" />
diff --cc src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 99f8575,db55c20..e452830
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@@ -112,153 -102,46 +112,156 @@@ public class DatabaseDescripto
  
      private static String localDC;
      private static Comparator<InetAddress> localComparator;
 +    private static EncryptionContext encryptionContext;
      private static boolean hasLoggedConfig;
  
 +    private static BackPressureStrategy backPressureStrategy;
 +    private static DiskOptimizationStrategy diskOptimizationStrategy;
 +
 +    private static boolean clientInitialized;
 +    private static boolean toolInitialized;
      private static boolean daemonInitialized;
  
 +    private static final int searchConcurrencyFactor = 
Integer.parseInt(System.getProperty(Config.PROPERTY_PREFIX + 
"search_concurrency_factor", "1"));
 +
 +    private static final boolean disableSTCSInL0 = 
Boolean.getBoolean(Config.PROPERTY_PREFIX + "disable_stcs_in_l0");
 +    private static final boolean unsafeSystem = 
Boolean.getBoolean(Config.PROPERTY_PREFIX + "unsafesystem");
 +
+     // turns some warnings into exceptions for testing
+     private static final boolean strictRuntimeChecks = 
Boolean.getBoolean("cassandra.strict.runtime.checks");
+ 
 -    public static boolean isDaemonInitialized()
 +    public static void daemonInitialization() throws ConfigurationException
      {
 -        return daemonInitialized;
 +        daemonInitialization(DatabaseDescriptor::loadConfig);
      }
  
 -    public static void setDaemonInitialized()
 +    public static void daemonInitialization(Supplier<Config> config) throws 
ConfigurationException
      {
 +        if (toolInitialized)
 +            throw new AssertionError("toolInitialization() already called");
 +        if (clientInitialized)
 +            throw new AssertionError("clientInitialization() already called");
 +
 +        // Some unit tests require this :(
 +        if (daemonInitialized)
 +            return;
          daemonInitialized = true;
 +
 +        setConfig(config.get());
 +        applyAll();
 +        AuthConfig.applyAuth();
 +    }
 +
 +    /**
 +     * Equivalent to {@link #toolInitialization(boolean) 
toolInitialization(true)}.
 +     */
 +    public static void toolInitialization()
 +    {
 +        toolInitialization(true);
      }
  
 -    public static void forceStaticInitialization() {}
 -    static
 +    /**
 +     * Initializes this class as a tool, which means that the configuration 
is loaded
 +     * using {@link #loadConfig()} and all non-daemon configuration parts 
will be setup.
 +     *
 +     * @param failIfDaemonOrClient if {@code true} and a call to {@link 
#daemonInitialization()} or
 +     *                             {@link #clientInitialization()} has been 
performed before, an
 +     *                             {@link AssertionError} will be thrown.
 +     */
 +    public static void toolInitialization(boolean failIfDaemonOrClient)
      {
 -        // In client mode, we use a default configuration. Note that the 
fields of this class will be
 -        // left unconfigured however (the partitioner or localDC will be null 
for instance) so this
 -        // should be used with care.
 -        try
 +        if (!failIfDaemonOrClient && (daemonInitialized || clientInitialized))
          {
 -            if (Config.isClientMode())
 -            {
 -                conf = new Config();
 -            }
 -            else
 -            {
 -                applyConfig(loadConfig());
 -            }
 +            return;
          }
 -        catch (Exception e)
 +        else
 +        {
 +            if (daemonInitialized)
 +                throw new AssertionError("daemonInitialization() already 
called");
 +            if (clientInitialized)
 +                throw new AssertionError("clientInitialization() already 
called");
 +        }
 +
 +        if (toolInitialized)
 +            return;
 +        toolInitialized = true;
 +
 +        setConfig(loadConfig());
 +
 +        applySimpleConfig();
 +
 +        applyPartitioner();
 +
 +        applySnitch();
 +
 +        applyEncryptionContext();
 +    }
 +
 +    /**
 +     * Equivalent to {@link #clientInitialization(boolean) 
clientInitialization(true)}.
 +     */
 +    public static void clientInitialization()
 +    {
 +        clientInitialization(true);
 +    }
 +
 +    /**
 +     * Initializes this class as a client, which means that just an empty 
configuration will
 +     * be used.
 +     *
 +     * @param failIfDaemonOrTool if {@code true} and a call to {@link 
#daemonInitialization()} or
 +     *                           {@link #toolInitialization()} has been 
performed before, an
 +     *                           {@link AssertionError} will be thrown.
 +     */
 +    public static void clientInitialization(boolean failIfDaemonOrTool)
 +    {
 +        if (!failIfDaemonOrTool && (daemonInitialized || toolInitialized))
 +        {
 +            return;
 +        }
 +        else
          {
 -            throw new ExceptionInInitializerError(e);
 +            if (daemonInitialized)
 +                throw new AssertionError("daemonInitialization() already 
called");
 +            if (toolInitialized)
 +                throw new AssertionError("toolInitialization() already 
called");
          }
 +
 +        if (clientInitialized)
 +            return;
 +        clientInitialized = true;
 +
 +        Config.setClientMode(true);
 +        conf = new Config();
 +        diskOptimizationStrategy = new SpinningDiskOptimizationStrategy();
 +    }
 +
 +    public static boolean isClientInitialized()
 +    {
 +        return clientInitialized;
 +    }
 +
 +    public static boolean isToolInitialized()
 +    {
 +        return toolInitialized;
 +    }
 +
 +    public static boolean isClientOrToolInitialized()
 +    {
 +        return clientInitialized || toolInitialized;
 +    }
 +
 +    public static boolean isDaemonInitialized()
 +    {
 +        return daemonInitialized;
      }
  
 +    public static Config getRawConfig()
 +    {
 +        return conf;
 +    }
 +
 +    @VisibleForTesting
      public static Config loadConfig() throws ConfigurationException
      {
          if (Config.getOverrideLoadConfig() != null)
@@@ -2462,71 -2109,8 +2465,76 @@@
          return conf.gc_warn_threshold_in_ms;
      }
  
 +    public static boolean isCDCEnabled()
 +    {
 +        return conf.cdc_enabled;
 +    }
 +
 +    public static void setCDCEnabled(boolean cdc_enabled)
 +    {
 +        conf.cdc_enabled = cdc_enabled;
 +    }
 +
 +    public static String getCDCLogLocation()
 +    {
 +        return conf.cdc_raw_directory;
 +    }
 +
 +    public static int getCDCSpaceInMB()
 +    {
 +        return conf.cdc_total_space_in_mb;
 +    }
 +
 +    @VisibleForTesting
 +    public static void setCDCSpaceInMB(int input)
 +    {
 +        conf.cdc_total_space_in_mb = input;
 +    }
 +
 +    public static int getCDCDiskCheckInterval()
 +    {
 +        return conf.cdc_free_space_check_interval_ms;
 +    }
 +
 +    @VisibleForTesting
 +    public static void setEncryptionContext(EncryptionContext ec)
 +    {
 +        encryptionContext = ec;
 +    }
 +
 +    public static int searchConcurrencyFactor()
 +    {
 +        return searchConcurrencyFactor;
 +    }
 +
 +    public static boolean isUnsafeSystem()
 +    {
 +        return unsafeSystem;
 +    }
 +
 +    public static void setBackPressureEnabled(boolean backPressureEnabled)
 +    {
 +        conf.back_pressure_enabled = backPressureEnabled;
 +    }
 +
 +    public static boolean backPressureEnabled()
 +    {
 +        return conf.back_pressure_enabled;
 +    }
 +
 +    @VisibleForTesting
 +    public static void setBackPressureStrategy(BackPressureStrategy strategy)
 +    {
 +        backPressureStrategy = strategy;
 +    }
 +
 +    public static BackPressureStrategy getBackPressureStrategy()
 +    {
 +        return backPressureStrategy;
 +    }
++
+     public static boolean strictRuntimeChecks()
+     {
+         return strictRuntimeChecks;
+     }
  }
diff --cc src/java/org/apache/cassandra/gms/Gossiper.java
index 0fd52ca,4ea0a4a..5d2e997
--- a/src/java/org/apache/cassandra/gms/Gossiper.java
+++ b/src/java/org/apache/cassandra/gms/Gossiper.java
@@@ -24,14 -23,17 +24,18 @@@ import java.util.*
  import java.util.Map.Entry;
  import java.util.concurrent.*;
  import java.util.concurrent.locks.ReentrantLock;
 +import javax.annotation.Nullable;
  
  import com.google.common.annotations.VisibleForTesting;
+ import com.google.common.base.Throwables;
  import com.google.common.collect.ImmutableList;
  import com.google.common.collect.ImmutableMap;
+ import com.google.common.util.concurrent.ListenableFutureTask;
  import com.google.common.util.concurrent.Uninterruptibles;
  
+ import io.netty.util.concurrent.FastThreadLocal;
  import org.apache.cassandra.utils.MBeanWrapper;
+ import org.apache.cassandra.utils.NoSpamLogger;
  import org.apache.cassandra.utils.Pair;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
diff --cc src/java/org/apache/cassandra/service/StorageService.java
index 8f4b1e7,a1f361d..e64cbaa
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@@ -712,42 -699,6 +712,42 @@@ public class StorageService extends Not
              doAuthSetup();
              logger.info("Not joining ring as requested. Use JMX 
(StorageService->joinRing()) to initiate ring joining");
          }
 +
 +        initialized = true;
 +    }
 +
 +    private void loadRingState()
 +    {
 +        if 
(Boolean.parseBoolean(System.getProperty("cassandra.load_ring_state", "true")))
 +        {
 +            logger.info("Loading persisted ring state");
 +            Multimap<InetAddress, Token> loadedTokens = 
SystemKeyspace.loadTokens();
 +            Map<InetAddress, UUID> loadedHostIds = 
SystemKeyspace.loadHostIds();
 +            for (InetAddress ep : loadedTokens.keySet())
 +            {
 +                if (ep.equals(FBUtilities.getBroadcastAddress()))
 +                {
 +                    // entry has been mistakenly added, delete it
 +                    SystemKeyspace.removeEndpoint(ep);
 +                }
 +                else
 +                {
 +                    if (loadedHostIds.containsKey(ep))
 +                        tokenMetadata.updateHostId(loadedHostIds.get(ep), ep);
-                     Gossiper.instance.addSavedEndpoint(ep);
++                    Gossiper.runInGossipStageBlocking(() -> 
Gossiper.instance.addSavedEndpoint(ep));
 +                }
 +            }
 +        }
 +    }
 +
 +    private boolean isReplacing()
 +    {
 +        if (System.getProperty("cassandra.replace_address_first_boot", null) 
!= null && SystemKeyspace.bootstrapComplete())
 +        {
 +            logger.info("Replace address on first boot requested; this node 
is already bootstrapped");
 +            return false;
 +        }
 +        return DatabaseDescriptor.getReplaceAddress() != null;
      }
  
      /**
diff --cc test/distributed/org/apache/cassandra/distributed/impl/Instance.java
index 07fd35d,94dbc96..382388b
--- a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java
+++ b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java
@@@ -349,15 -348,18 +349,19 @@@ public class Instance extends IsolatedE
              for (int i = 0; i < tokens.size(); i++)
              {
                  InetAddressAndPort ep = hosts.get(i);
-                 Gossiper.instance.initializeNodeUnsafe(ep.address, 
hostIds.get(i), 1);
-                 Gossiper.instance.injectApplicationState(ep.address,
-                         ApplicationState.TOKENS,
-                         new 
VersionedValue.VersionedValueFactory(partitioner).tokens(Collections.singleton(tokens.get(i))));
-                 storageService.onChange(ep.address,
-                         ApplicationState.STATUS,
-                         new 
VersionedValue.VersionedValueFactory(partitioner).normal(Collections.singleton(tokens.get(i))));
-                 Gossiper.instance.realMarkAlive(ep.address, 
Gossiper.instance.getEndpointStateForEndpoint(ep.address));
+                 UUID hostId = hostIds.get(i);
+                 Token token = tokens.get(i);
+                 Gossiper.runInGossipStageBlocking(() -> {
+                     Gossiper.instance.initializeNodeUnsafe(ep.address, 
hostId, 1);
+                     Gossiper.instance.injectApplicationState(ep.address,
+                                                              
ApplicationState.TOKENS,
+                                                              new 
VersionedValue.VersionedValueFactory(partitioner).tokens(Collections.singleton(token)));
+                     storageService.onChange(ep.address,
+                                             ApplicationState.STATUS,
+                                             new 
VersionedValue.VersionedValueFactory(partitioner).normal(Collections.singleton(token)));
+                     Gossiper.instance.realMarkAlive(ep.address, 
Gossiper.instance.getEndpointStateForEndpoint(ep.address));
+                 });
 +
                  int version = Math.min(MessagingService.current_version, 
cluster.get(ep).getMessagingVersion());
                  MessagingService.instance().setVersion(ep.address, version);
              }
diff --cc test/unit/org/apache/cassandra/gms/GossiperTest.java
index def0530,f23c016..448620a
--- a/test/unit/org/apache/cassandra/gms/GossiperTest.java
+++ b/test/unit/org/apache/cassandra/gms/GossiperTest.java
@@@ -47,16 -45,11 +47,17 @@@ import static org.junit.Assert.assertTr
  
  public class GossiperTest
  {
 -    static
 +    @BeforeClass
 +    public static void before()
      {
+         System.setProperty(Gossiper.Props.DISABLE_THREAD_VALIDATION, "true");
 -        DatabaseDescriptor.setDaemonInitialized();
 +        DatabaseDescriptor.daemonInitialization();
 +        SchemaLoader.prepareServer();
 +        SchemaLoader.createKeyspace("schema_test_ks",
 +                                    KeyspaceParams.simple(1),
 +                                    
SchemaLoader.standardCFMD("schema_test_ks", "schema_test_cf"));
      }
 +
      static final IPartitioner partitioner = new RandomPartitioner();
      StorageService ss = StorageService.instance;
      TokenMetadata tmd = StorageService.instance.getTokenMetadata();
diff --cc test/unit/org/apache/cassandra/locator/CloudstackSnitchTest.java
index 34f8204,5dc34df..bc3e837
--- a/test/unit/org/apache/cassandra/locator/CloudstackSnitchTest.java
+++ b/test/unit/org/apache/cassandra/locator/CloudstackSnitchTest.java
@@@ -45,7 -45,8 +45,8 @@@ public class CloudstackSnitchTes
      @BeforeClass
      public static void setup() throws Exception
      {
+         System.setProperty(Gossiper.Props.DISABLE_THREAD_VALIDATION, "true");
 -        DatabaseDescriptor.setDaemonInitialized();
 +        DatabaseDescriptor.daemonInitialization();
          SchemaLoader.mkdirs();
          SchemaLoader.cleanup();
          Keyspace.setInitialized();
diff --cc test/unit/org/apache/cassandra/locator/EC2SnitchTest.java
index 5e99523,9d078ce..0c71c92
--- a/test/unit/org/apache/cassandra/locator/EC2SnitchTest.java
+++ b/test/unit/org/apache/cassandra/locator/EC2SnitchTest.java
@@@ -50,7 -50,8 +50,8 @@@ public class EC2SnitchTes
      @BeforeClass
      public static void setup() throws Exception
      {
+         System.setProperty(Gossiper.Props.DISABLE_THREAD_VALIDATION, "true");
 -        DatabaseDescriptor.setDaemonInitialized();
 +        DatabaseDescriptor.daemonInitialization();
          SchemaLoader.mkdirs();
          SchemaLoader.cleanup();
          Keyspace.setInitialized();
diff --cc test/unit/org/apache/cassandra/locator/GoogleCloudSnitchTest.java
index c63044c,04b71e9..2491ba9
--- a/test/unit/org/apache/cassandra/locator/GoogleCloudSnitchTest.java
+++ b/test/unit/org/apache/cassandra/locator/GoogleCloudSnitchTest.java
@@@ -46,7 -46,8 +46,8 @@@ public class GoogleCloudSnitchTes
      @BeforeClass
      public static void setup() throws Exception
      {
+         System.setProperty(Gossiper.Props.DISABLE_THREAD_VALIDATION, "true");
 -        DatabaseDescriptor.setDaemonInitialized();
 +        DatabaseDescriptor.daemonInitialization();
          SchemaLoader.mkdirs();
          SchemaLoader.cleanup();
          Keyspace.setInitialized();


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to