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

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 9bf62e205 keep EventCountCircuitBreaker event count from wrapping on 
int overflow (#1825)
9bf62e205 is described below

commit 9bf62e20594f049195d1eed167decec6dca42f3d
Author: alhuda <[email protected]>
AuthorDate: Mon Oct 19 03:51:50 2026 +0530

    keep EventCountCircuitBreaker event count from wrapping on int overflow 
(#1825)
    
    CheckIntervalData.increment summed the increments of a check interval in
    int arithmetic. incrementAndCheckState(Integer) accepts any non-negative
    increment, so once one interval's events pass Integer.MAX_VALUE the
    count wraps negative: a closed breaker then never opens, and an open
    breaker sees a count below the closing threshold and closes at the next
    interval. Widen the private counter to long; thresholds stay int.
---
 .../lang3/concurrent/EventCountCircuitBreaker.java |  6 ++---
 .../concurrent/EventCountCircuitBreakerTest.java   | 28 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreaker.java
 
b/src/main/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreaker.java
index fc9bef911..be508d450 100644
--- 
a/src/main/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreaker.java
+++ 
b/src/main/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreaker.java
@@ -189,7 +189,7 @@ public abstract boolean 
isStateTransition(EventCountCircuitBreaker breaker,
     private static final class CheckIntervalData {
 
         /** The counter for events. */
-        private final int eventCount;
+        private final long eventCount;
 
         /** The start time of the current check interval. */
         private final long checkIntervalStart;
@@ -200,7 +200,7 @@ private static final class CheckIntervalData {
          * @param count The current count value
          * @param intervalStart The start time of the check interval
          */
-        CheckIntervalData(final int count, final long intervalStart) {
+        CheckIntervalData(final long count, final long intervalStart) {
             eventCount = count;
             checkIntervalStart = intervalStart;
         }
@@ -219,7 +219,7 @@ public long getCheckIntervalStart() {
          *
          * @return The number of received events
          */
-        public int getEventCount() {
+        public long getEventCount() {
             return eventCount;
         }
 
diff --git 
a/src/test/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreakerTest.java
 
b/src/test/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreakerTest.java
index 8bbe62e72..5e2d57441 100644
--- 
a/src/test/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreakerTest.java
+++ 
b/src/test/java/org/apache/commons/lang3/concurrent/EventCountCircuitBreakerTest.java
@@ -285,6 +285,34 @@ void testNotClosingOverThreshold() {
         assertTrue(breaker.isOpen(), "Not open at end");
     }
 
+    /**
+     * Tests that an open circuit breaker does not close itself when the event 
count of the
+     * check interval exceeds the range of an int.
+     */
+    @Test
+    void testNotClosingWhenEventCountOverflows() {
+        final EventCountCircuitBreakerTestImpl breaker = new 
EventCountCircuitBreakerTestImpl(OPENING_THRESHOLD,
+                10, TimeUnit.SECONDS, CLOSING_THRESHOLD, 1, TimeUnit.SECONDS);
+        breaker.at(0).open();
+        
assertFalse(breaker.at(1000).incrementAndCheckState(CLOSING_THRESHOLD), "Not 
open");
+        
assertFalse(breaker.at(2000).incrementAndCheckState(Integer.MAX_VALUE), "Not 
open");
+        assertFalse(breaker.at(NANO_FACTOR + 3000).incrementAndCheckState(), 
"Closed in new interval");
+        assertTrue(breaker.isOpen(), "Not open at end");
+    }
+
+    /**
+     * Tests that the circuit breaker opens when the event count of the check 
interval
+     * exceeds the range of an int.
+     */
+    @Test
+    void testOpeningWhenEventCountOverflows() {
+        final EventCountCircuitBreakerTestImpl breaker = new 
EventCountCircuitBreakerTestImpl(OPENING_THRESHOLD, 1,
+            TimeUnit.SECONDS, CLOSING_THRESHOLD, 1, TimeUnit.SECONDS);
+        assertTrue(breaker.at(1000).incrementAndCheckState(OPENING_THRESHOLD / 
2), "Not closed");
+        
assertFalse(breaker.at(2000).incrementAndCheckState(Integer.MAX_VALUE), "Not 
open");
+        assertTrue(breaker.isOpen(), "Not open at end");
+    }
+
     /**
      * Tests that the circuit breaker stays closed if there are a number of 
received
      * events, but not in a single check interval.

Reply via email to