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

dcapwell pushed a commit to branch cep-15-accord
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/cep-15-accord by this push:
     new 7eff02deed When bootstrap fails the retry field is not populated which 
leads to a NPE
7eff02deed is described below

commit 7eff02deed57c52ab8af06d8d245d8a531b01473
Author: David Capwell <[email protected]>
AuthorDate: Sat Mar 8 14:36:28 2025 -0800

    When bootstrap fails the retry field is not populated which leads to a NPE
    
    patch by David Capwell; reviewed by Benedict Elliott Smith for 
CASSANDRA-20417
---
 .../org/apache/cassandra/config/AccordSpec.java    | 11 +++---
 .../cassandra/config/DatabaseDescriptor.java       | 36 -----------------
 .../cassandra/config/StringRetryStrategy.java      | 46 ++++++++++++++++++++++
 .../service/accord/api/AccordWaitStrategies.java   | 27 ++++++++-----
 .../config/DatabaseDescriptorRefTest.java          | 17 ++++++++
 .../service/accord/FetchMinEpochTest.java          |  3 +-
 6 files changed, 88 insertions(+), 52 deletions(-)

diff --git a/src/java/org/apache/cassandra/config/AccordSpec.java 
b/src/java/org/apache/cassandra/config/AccordSpec.java
index d968f3ada0..469c949147 100644
--- a/src/java/org/apache/cassandra/config/AccordSpec.java
+++ b/src/java/org/apache/cassandra/config/AccordSpec.java
@@ -137,7 +137,7 @@ public class AccordSpec
     public DurationSpec.IntMillisecondsBound range_syncpoint_timeout = new 
DurationSpec.IntMillisecondsBound("3m");
     public DurationSpec.IntMillisecondsBound repair_timeout = new 
DurationSpec.IntMillisecondsBound("10m");
     public String recover_txn = "5s*attempts <= 60s";
-    public String recover_syncpoint = "60s <= 30s*attempts...60s*attempts <= 
600s";
+    public StringRetryStrategy recover_syncpoint = new 
StringRetryStrategy("60s <= 30s*attempts...60s*attempts <= 600s");
     public String fetch_txn = "1s*attempts";
     public String fetch_syncpoint = "5s*attempts";
     public String expire_txn = "5s*attempts";
@@ -148,10 +148,11 @@ public class AccordSpec
     public String slow_syncpoint_preaccept = "10s";
     public String slow_txn_preaccept = "30ms <= p50*2 <= 100ms";
     public String slow_read = "30ms <= p50*2 <= 100ms";
-    public String retry_syncpoint = "10s*attempts <= 600s";
-    public String retry_durability = "10s*attempts <= 600s";
-    public String retry_fetch_min_epoch = "200ms...1s*attempts <= 
1s,retries=3";
-    public String retry_fetch_topology = "200ms...1s*attempts <= 
1s,retries=100";
+    public StringRetryStrategy retry_syncpoint = new 
StringRetryStrategy("10s*attempts <= 600s");
+    public StringRetryStrategy retry_durability = new 
StringRetryStrategy("10s*attempts <= 600s");
+    public StringRetryStrategy retry_bootstrap = new 
StringRetryStrategy("10s*attempts <= 600s");
+    public StringRetryStrategy retry_fetch_min_epoch = new 
StringRetryStrategy("200ms...1s*attempts <= 1s,retries=3");
+    public StringRetryStrategy retry_fetch_topology = new 
StringRetryStrategy("200ms...1s*attempts <= 1s,retries=100");
 
     public volatile DurationSpec.IntSecondsBound fast_path_update_delay = null;
 
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java 
b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index ac53c87222..aa4c25af00 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -5181,28 +5181,12 @@ public class DatabaseDescriptor
         conf.accord.expire_txn = expireTxnDelay;
     }
 
-    public static String getAccordRecoverSyncPointDelay()
-    {
-        return conf.accord.recover_syncpoint;
-    }
-
-    public static void setAccordRecoverSyncPointDelay(String 
recoverSyncPointDelay)
-    {
-        AccordWaitStrategies.setRecoverSyncPoint(recoverSyncPointDelay);
-        conf.accord.recover_syncpoint = recoverSyncPointDelay;
-    }
-
     public static long getAccordFastPathUpdateDelayMillis()
     {
         DurationSpec.IntSecondsBound bound = 
conf.accord.fast_path_update_delay;
         return bound == null ? -1 : bound.to(TimeUnit.MILLISECONDS);
     }
 
-    public static void setAccordFastPathUpdateDelaySeconds(long seconds)
-    {
-        conf.accord.fast_path_update_delay = new 
DurationSpec.IntSecondsBound(seconds);
-    }
-
     public static long getAccordGCDelay(TimeUnit unit)
     {
         return conf.accord.gc_delay.to(unit);
@@ -5213,41 +5197,21 @@ public class DatabaseDescriptor
         return conf.accord.shard_durability_target_splits;
     }
 
-    public static void setAccordShardDurabilityTargetSplits(int number)
-    {
-        conf.accord.shard_durability_target_splits = number;
-    }
-
     public static long getAccordScheduleDurabilityTxnIdLag(TimeUnit unit)
     {
         return conf.accord.durability_txnid_lag.to(unit);
     }
 
-    public static void setAccordScheduleDurabilityTxnIdLagSeconds(long seconds)
-    {
-        conf.accord.durability_txnid_lag = new 
DurationSpec.IntSecondsBound(seconds);
-    }
-
     public static long getAccordGlobalDurabilityCycle(TimeUnit unit)
     {
         return conf.accord.global_durability_cycle.to(unit);
     }
 
-    public static void setAccordGlobalDurabilityCycleSeconds(long seconds)
-    {
-        conf.accord.global_durability_cycle = new 
DurationSpec.IntSecondsBound(seconds);
-    }
-
     public static long getAccordShardDurabilityCycle(TimeUnit unit)
     {
         return conf.accord.shard_durability_cycle.to(unit);
     }
 
-    public static void setAccordShardDurabilityCycleSeconds(long seconds)
-    {
-        conf.accord.shard_durability_cycle = new 
DurationSpec.IntSecondsBound(seconds);
-    }
-
     public static boolean getAccordStateCacheListenerJFREnabled()
     {
         return conf.accord.state_cache_listener_jfr_enabled;
diff --git a/src/java/org/apache/cassandra/config/StringRetryStrategy.java 
b/src/java/org/apache/cassandra/config/StringRetryStrategy.java
new file mode 100644
index 0000000000..6003c6591a
--- /dev/null
+++ b/src/java/org/apache/cassandra/config/StringRetryStrategy.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.apache.cassandra.service.RetryStrategy;
+
+import static 
org.apache.cassandra.service.TimeoutStrategy.LatencySourceFactory.none;
+
+public class StringRetryStrategy
+{
+    private final String spec;
+    private final RetryStrategy retry;
+
+    public StringRetryStrategy(String spec)
+    {
+        this.spec = spec;
+        this.retry = RetryStrategy.parse(spec, none());
+    }
+
+    public RetryStrategy retry()
+    {
+        return retry;
+    }
+
+    @Override
+    public String toString()
+    {
+        return spec;
+    }
+}
diff --git 
a/src/java/org/apache/cassandra/service/accord/api/AccordWaitStrategies.java 
b/src/java/org/apache/cassandra/service/accord/api/AccordWaitStrategies.java
index b5d990c091..e60d340b97 100644
--- a/src/java/org/apache/cassandra/service/accord/api/AccordWaitStrategies.java
+++ b/src/java/org/apache/cassandra/service/accord/api/AccordWaitStrategies.java
@@ -23,6 +23,7 @@ import javax.annotation.Nullable;
 import accord.primitives.TxnId;
 import org.apache.cassandra.config.AccordSpec;
 import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.config.StringRetryStrategy;
 import org.apache.cassandra.net.Verb;
 import org.apache.cassandra.service.RetryStrategy;
 import org.apache.cassandra.service.TimeoutStrategy;
@@ -96,6 +97,7 @@ public class AccordWaitStrategies
         setRecoverSyncPoint(config.recover_syncpoint);
         setRetrySyncPoint(config.retry_syncpoint);
         setRetryDurability(config.retry_durability);
+        setRetryBootstrap(config.retry_bootstrap);
         setRetryFetchMinEpoch(config.retry_fetch_min_epoch);
         setRetryFetchTopology(config.retry_fetch_topology);
     }
@@ -150,29 +152,34 @@ public class AccordWaitStrategies
         recoverTxn = RetryStrategy.parse(spec, rw(accordReadMetrics, 
accordWriteMetrics));
     }
 
-    public static void setRecoverSyncPoint(String spec)
+    public static void setRecoverSyncPoint(StringRetryStrategy spec)
     {
-        recoverSyncPoint = RetryStrategy.parse(spec, none());
+        recoverSyncPoint = spec.retry();
     }
 
-    public static void setRetrySyncPoint(String spec)
+    public static void setRetrySyncPoint(StringRetryStrategy spec)
     {
-        retrySyncPoint = RetryStrategy.parse(spec, none());
+        retrySyncPoint = spec.retry();
     }
 
-    public static void setRetryDurability(String spec)
+    public static void setRetryDurability(StringRetryStrategy spec)
     {
-        retryDurability = RetryStrategy.parse(spec, none());
+        retryDurability = spec.retry();
     }
 
-    public static void setRetryFetchMinEpoch(String spec)
+    public static void setRetryBootstrap(StringRetryStrategy spec)
     {
-        retryFetchMinEpoch = RetryStrategy.parse(spec, none());
+        retryBootstrap = spec.retry();
     }
 
-    public static void setRetryFetchTopology(String spec)
+    public static void setRetryFetchMinEpoch(StringRetryStrategy spec)
     {
-        retryFetchTopology = RetryStrategy.parse(spec, none());
+        retryFetchMinEpoch = spec.retry();
+    }
+
+    public static void setRetryFetchTopology(StringRetryStrategy spec)
+    {
+        retryFetchTopology = spec.retry();
     }
 
     static RetryStrategy recover(TxnId txnId)
diff --git 
a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java 
b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java
index a3b2cb91e9..3d6ebc57e2 100644
--- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java
+++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java
@@ -162,6 +162,7 @@ public class DatabaseDescriptorRefTest
     "org.apache.cassandra.config.StartupChecksOptions",
     "org.apache.cassandra.config.StartupChecksOptions",
     "org.apache.cassandra.config.StorageAttachedIndexOptions",
+    "org.apache.cassandra.config.StringRetryStrategy",
     "org.apache.cassandra.config.SubnetGroups",
     "org.apache.cassandra.config.SubnetGroups",
     "org.apache.cassandra.config.TrackWarnings",
@@ -291,6 +292,22 @@ public class DatabaseDescriptorRefTest
     "org.apache.cassandra.security.SSLFactory",
     "org.apache.cassandra.service.CacheService$CacheType",
     "org.apache.cassandra.service.consensus.TransactionalMode",
+    "org.apache.cassandra.service.TimeoutStrategy$LatencySourceFactory",
+    "org.apache.cassandra.service.TimeoutStrategy$LatencySource",
+    "org.apache.cassandra.service.RetryStrategy",
+    "org.apache.cassandra.service.RetryStrategy$WaitRandomizerFactory",
+    "org.apache.cassandra.service.RetryStrategy$1",
+    "org.apache.cassandra.service.RetryStrategy$WaitRandomizer",
+    "org.apache.cassandra.service.TimeoutStrategy",
+    "org.apache.cassandra.service.TimeoutStrategy$LatencyModifierFactory",
+    "org.apache.cassandra.service.TimeoutStrategy$Wait",
+    "org.apache.cassandra.service.TimeoutStrategy$LatencySupplier",
+    "org.apache.cassandra.service.TimeoutStrategy$1",
+    "org.apache.cassandra.service.TimeoutStrategy$LatencySupplier$Constant",
+    "org.apache.cassandra.service.TimeoutStrategy$LatencyModifier",
+    "org.apache.cassandra.service.TimeoutStrategy$Wait$Modifying",
+    "org.apache.cassandra.service.TimeoutStrategy$Wait$Constant",
+    "org.apache.cassandra.service.RetryStrategy$WaitRandomizerFactory$Uniform",
     "org.apache.cassandra.service.WaitStrategy",
     "org.apache.cassandra.transport.ProtocolException",
     "org.apache.cassandra.utils.Closeable",
diff --git 
a/test/unit/org/apache/cassandra/service/accord/FetchMinEpochTest.java 
b/test/unit/org/apache/cassandra/service/accord/FetchMinEpochTest.java
index 5c1e2c5a81..1c3db5939c 100644
--- a/test/unit/org/apache/cassandra/service/accord/FetchMinEpochTest.java
+++ b/test/unit/org/apache/cassandra/service/accord/FetchMinEpochTest.java
@@ -35,6 +35,7 @@ import accord.utils.Gen;
 import accord.utils.Gens;
 import accord.utils.RandomSource;
 import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.config.StringRetryStrategy;
 import org.apache.cassandra.dht.Murmur3Partitioner;
 import org.apache.cassandra.io.IVersionedSerializers;
 import org.apache.cassandra.io.util.DataOutputBuffer;
@@ -65,7 +66,7 @@ public class FetchMinEpochTest
 
     private static void boundedRetries(int retries)
     {
-        
AccordWaitStrategies.setRetryFetchMinEpoch("0<=200ms*2^attempts<=60s,retries=" 
+ retries);
+        AccordWaitStrategies.setRetryFetchMinEpoch(new 
StringRetryStrategy("0<=200ms*2^attempts<=60s,retries=" + retries));
     }
 
     @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to