Skip to content

Commit 97bbbd1

Browse files
authored
fix: ensure requests are blocked when errRatioThreshold reaches 100% (#1856) (#1857)
1 parent 222670e commit 97bbbd1

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/AbstractCircuitBreaker.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* @since 1.8.0
3232
*/
3333
public abstract class AbstractCircuitBreaker implements CircuitBreaker {
34+
protected static final double MAX_RATIO = 1.0d;
3435

3536
protected final DegradeRule rule;
3637
protected final int recoveryTimeoutMs;
@@ -122,7 +123,7 @@ public void accept(Context context, Entry entry) {
122123
}
123124
return false;
124125
}
125-
126+
126127
private void notifyObservers(CircuitBreaker.State prevState, CircuitBreaker.State newState, Double snapshotValue) {
127128
for (CircuitBreakerStateChangeObserver observer : observerRegistry.getStateChangeObservers()) {
128129
observer.onStateChange(prevState, newState, rule, snapshotValue);

sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ExceptionCircuitBreaker.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ private void handleStateChangeWhenThresholdExceeded(Throwable error) {
106106
if (strategy == DEGRADE_GRADE_EXCEPTION_RATIO) {
107107
// Use errorRatio
108108
curCount = errCount * 1.0d / totalCount;
109+
// special case when ratio equals 1.0
110+
if (Double.compare(curCount, threshold) == 0 && Double.compare(threshold, MAX_RATIO) == 0) {
111+
transformToOpen(curCount);
112+
return;
113+
}
109114
}
110115
if (curCount > threshold) {
111116
transformToOpen(curCount);

sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreaker.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
* @since 1.8.0
3333
*/
3434
public class ResponseTimeCircuitBreaker extends AbstractCircuitBreaker {
35-
36-
private static final double SLOW_REQUEST_RATIO_MAX_VALUE = 1.0d;
37-
3835
private final long maxAllowedRt;
3936
private final double maxSlowRequestRatio;
4037
private final int minRequestAmount;
@@ -112,7 +109,7 @@ private void handleStateChangeWhenThresholdExceeded(long rt) {
112109
transformToOpen(currentRatio);
113110
}
114111
if (Double.compare(currentRatio, maxSlowRequestRatio) == 0 &&
115-
Double.compare(maxSlowRequestRatio, SLOW_REQUEST_RATIO_MAX_VALUE) == 0) {
112+
Double.compare(maxSlowRequestRatio, MAX_RATIO) == 0) {
116113
transformToOpen(currentRatio);
117114
}
118115
}

sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ExceptionCircuitBreakerTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.util.ArrayList;
2222
import java.util.Arrays;
23+
import java.util.Collections;
2324

2425
import com.alibaba.csp.sentinel.util.TimeUtil;
2526
import org.junit.After;
@@ -86,4 +87,29 @@ public void testRecordErrorOrSuccess() throws BlockException {
8687
assertTrue(entryAndSleepFor(mocked, resource, 100));
8788
}
8889
}
90+
91+
@Test
92+
public void testMaxErrorRatioThreshold() {
93+
String resource = "testMaxErrorRatioThreshold";
94+
DegradeRule rule = new DegradeRule("resource")
95+
.setCount(1)
96+
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
97+
.setMinRequestAmount(3)
98+
.setStatIntervalMs(5000)
99+
.setTimeWindow(5);
100+
rule.setResource(resource);
101+
DegradeRuleManager.loadRules(Collections.singletonList(rule));
102+
103+
assertTrue(entryWithErrorIfPresent(resource, new RuntimeException()));
104+
assertTrue(entryWithErrorIfPresent(resource, new RuntimeException()));
105+
assertTrue(entryWithErrorIfPresent(resource, new RuntimeException()));
106+
107+
// should be blocked, cause 3/3 requests' rt is bigger than max rt.
108+
assertFalse(entryWithErrorIfPresent(resource, new RuntimeException()));
109+
assertFalse(entryWithErrorIfPresent(resource, new RuntimeException()));
110+
111+
sleep(5000);
112+
113+
assertTrue(entryWithErrorIfPresent(resource, new RuntimeException()));
114+
}
89115
}

0 commit comments

Comments
 (0)