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

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


The following commit(s) were added to refs/heads/cassandra-5.0 by this push:
     new f8f456f0f6 Fix default max interval calculation in FailureDetector
f8f456f0f6 is described below

commit f8f456f0f674090652e64ac4f5aa276bf81f621d
Author: Sam Tunnicliffe <[email protected]>
AuthorDate: Fri Nov 21 17:19:52 2025 +0000

    Fix default max interval calculation in FailureDetector
    
    Patch by Sam Tunnicliffe; reviewed by Maxim Muzafarov and Stefan Miklosovic
    for CASSANDRA-21025
---
 CHANGES.txt                                        |  1 +
 .../org/apache/cassandra/gms/FailureDetector.java  | 17 +++++++++--
 .../apache/cassandra/gms/FailureDetectorTest.java  | 35 ++++++++++++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index f6dfe4045a..d98f1b69ec 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 5.0.7
+ * Correctly calculate default for FailureDetector max interval 
(CASSANDRA-21025)
  * Adding missing configs in system_views.settings to be backward compatible 
(CASSANDRA-20863)
  * Heap dump should not be generated on handled exceptions (CASSANDRA-20974)
 Merged from 4.1:
diff --git a/src/java/org/apache/cassandra/gms/FailureDetector.java 
b/src/java/org/apache/cassandra/gms/FailureDetector.java
index 9cf7ad0392..c2e148de1f 100644
--- a/src/java/org/apache/cassandra/gms/FailureDetector.java
+++ b/src/java/org/apache/cassandra/gms/FailureDetector.java
@@ -43,6 +43,7 @@ import javax.management.openmbean.TabularData;
 import javax.management.openmbean.TabularDataSupport;
 import javax.management.openmbean.TabularType;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -416,6 +417,17 @@ public class FailureDetector implements IFailureDetector, 
FailureDetectorMBean
         
sb.append("-----------------------------------------------------------------------");
         return sb.toString();
     }
+
+    /**
+     * Only for testing. In production code, ArrivalWindow instances call 
getMaxInterval() during
+     * intitialization and use the value to set the private final field 
MAX_INTERVAL_IN_NANO
+     * @return the value that would be used for to populate any new 
ArrivalWindow instance
+     */
+    @VisibleForTesting
+    static long calculateMaxInterval()
+    {
+        return ArrivalWindow.getMaxInterval();
+    }
 }
 
 /*
@@ -485,9 +497,10 @@ class ArrivalWindow
         arrivalIntervals = new ArrayBackedBoundedStats(size);
     }
 
-    private static long getMaxInterval()
+    @VisibleForTesting
+    static long getMaxInterval()
     {
-        long newValue = 
FD_MAX_INTERVAL_MS.getLong(FailureDetector.INITIAL_VALUE_NANOS);
+        long newValue = 
FD_MAX_INTERVAL_MS.getLong(TimeUnit.NANOSECONDS.toMillis(FailureDetector.INITIAL_VALUE_NANOS));
         if (newValue != FailureDetector.INITIAL_VALUE_NANOS)
             logger.info("Overriding {} from {}ms to {}ms", 
FD_MAX_INTERVAL_MS.getKey(), FailureDetector.INITIAL_VALUE_NANOS, newValue);
         return TimeUnit.NANOSECONDS.convert(newValue, TimeUnit.MILLISECONDS);
diff --git a/test/unit/org/apache/cassandra/gms/FailureDetectorTest.java 
b/test/unit/org/apache/cassandra/gms/FailureDetectorTest.java
index 8ec3dae913..32524cef9e 100644
--- a/test/unit/org/apache/cassandra/gms/FailureDetectorTest.java
+++ b/test/unit/org/apache/cassandra/gms/FailureDetectorTest.java
@@ -23,11 +23,13 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.TimeUnit;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import org.apache.cassandra.Util;
+import org.apache.cassandra.config.CassandraRelevantProperties;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.commitlog.CommitLog;
 import org.apache.cassandra.dht.IPartitioner;
@@ -38,6 +40,7 @@ import org.apache.cassandra.locator.TokenMetadata;
 import org.apache.cassandra.service.StorageService;
 
 import static 
org.apache.cassandra.config.CassandraRelevantProperties.MAX_LOCAL_PAUSE_IN_MS;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
 public class FailureDetectorTest
@@ -87,4 +90,36 @@ public class FailureDetectorTest
         FailureDetector.instance.interpret(leftHost);
         assertFalse("Left endpoint not convicted", 
FailureDetector.instance.isAlive(leftHost));
     }
+
+    @Test
+    public void testMaxIntervalCalculation()
+    {
+        // Default value for ArrivalWindow.MAX_INTERVAL_IN_NANO, which is 
supplied by
+        // ArrivalWindow::getMaxInterval should be 2000000000ns/2 seconds.
+        Long initialPropertyValue = 
CassandraRelevantProperties.FD_MAX_INTERVAL_MS.isPresent()
+                                    ? 
CassandraRelevantProperties.FD_MAX_INTERVAL_MS.getLong()
+                                    : null;
+        try
+        {
+            // verify that max interval isn't being set directly using system 
property
+            CassandraRelevantProperties.FD_MAX_INTERVAL_MS.reset();
+            
assertFalse(CassandraRelevantProperties.FD_MAX_INTERVAL_MS.isPresent());
+            // in which case, max interval should default to 
INITIAL_VALUE_NANOS
+            assertEquals(FailureDetector.INITIAL_VALUE_NANOS, 
FailureDetector.calculateMaxInterval());
+
+            // max interval can be overridden, but it's value should be 
supplied in millis
+            long overrideMillis = 
TimeUnit.NANOSECONDS.toMillis(FailureDetector.INITIAL_VALUE_NANOS * 2);
+            
CassandraRelevantProperties.FD_MAX_INTERVAL_MS.setLong(overrideMillis);
+            // max interval is a nanos value, so convert the override to get 
the expected value
+            long expectedNanos = TimeUnit.NANOSECONDS.convert(overrideMillis, 
TimeUnit.MILLISECONDS);
+            assertEquals(expectedNanos, 
FailureDetector.calculateMaxInterval());
+        }
+        finally
+        {
+            if (initialPropertyValue == null)
+                CassandraRelevantProperties.FD_MAX_INTERVAL_MS.reset();
+            else
+                
CassandraRelevantProperties.FD_MAX_INTERVAL_MS.setLong(initialPropertyValue);
+        }
+    }
 }


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

Reply via email to