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.