Repository navigation
Description
success_rate_ejection.enforcement_percentage defaults to 100% per Envoy and our spec:
This is implemented (correctly) here:
grpc-java/xds/src/main/java/io/grpc/xds/EnvoyServerProtoData.java
Lines 379 to 396 in ed3bf6b
| SuccessRateEjection successRateEjection; | |
| // If success rate enforcement has been turned completely off, don't configure this ejection. | |
| if (envoyOutlierDetection.hasEnforcingSuccessRate() | |
| && envoyOutlierDetection.getEnforcingSuccessRate().getValue() == 0) { | |
| successRateEjection = null; | |
| } else { | |
| Integer stdevFactor = envoyOutlierDetection.hasSuccessRateStdevFactor() | |
| ? envoyOutlierDetection.getSuccessRateStdevFactor().getValue() : null; | |
| Integer enforcementPercentage = envoyOutlierDetection.hasEnforcingSuccessRate() | |
| ? envoyOutlierDetection.getEnforcingSuccessRate().getValue() : null; | |
| Integer minimumHosts = envoyOutlierDetection.hasSuccessRateMinimumHosts() | |
| ? envoyOutlierDetection.getSuccessRateMinimumHosts().getValue() : null; | |
| Integer requestVolume = envoyOutlierDetection.hasSuccessRateRequestVolume() | |
| ? envoyOutlierDetection.getSuccessRateRequestVolume().getValue() : null; | |
| successRateEjection = SuccessRateEjection.create(stdevFactor, enforcementPercentage, | |
| minimumHosts, requestVolume); | |
| } |
But failure_percent_ejection should default to zero instead (i.e. disable checking when unset):
This is implemented (incorrectly) here:
grpc-java/xds/src/main/java/io/grpc/xds/EnvoyServerProtoData.java
Lines 398 to 414 in ed3bf6b
| FailurePercentageEjection failurePercentageEjection; | |
| if (envoyOutlierDetection.hasEnforcingFailurePercentage() | |
| && envoyOutlierDetection.getEnforcingFailurePercentage().getValue() == 0) { | |
| failurePercentageEjection = null; | |
| } else { | |
| Integer threshold = envoyOutlierDetection.hasFailurePercentageThreshold() | |
| ? envoyOutlierDetection.getFailurePercentageThreshold().getValue() : null; | |
| Integer enforcementPercentage = envoyOutlierDetection.hasEnforcingFailurePercentage() | |
| ? envoyOutlierDetection.getEnforcingFailurePercentage().getValue() : null; | |
| Integer minimumHosts = envoyOutlierDetection.hasFailurePercentageMinimumHosts() | |
| ? envoyOutlierDetection.getFailurePercentageMinimumHosts().getValue() : null; | |
| Integer requestVolume = envoyOutlierDetection.hasFailurePercentageRequestVolume() | |
| ? envoyOutlierDetection.getFailurePercentageRequestVolume().getValue() : null; | |
| failurePercentageEjection = FailurePercentageEjection.create(threshold, | |
| enforcementPercentage, minimumHosts, requestVolume); | |
| } |
Note that it's a copy/paste of the enforcement_percentage above it, meaning it is only disabled if it is explicitly set to zero.
When we go to actually build the enforcer, failurePercentage is non-null:
grpc-java/xds/src/main/java/io/grpc/xds/CdsLoadBalancer2.java
Lines 632 to 652 in ed3bf6b
| FailurePercentageEjection failurePercentage = outlierDetection.failurePercentageEjection(); | |
| if (failurePercentage != null) { | |
| OutlierDetectionLoadBalancerConfig.FailurePercentageEjection.Builder | |
| failurePercentageConfigBuilder = new OutlierDetectionLoadBalancerConfig | |
| .FailurePercentageEjection.Builder(); | |
| if (failurePercentage.threshold() != null) { | |
| failurePercentageConfigBuilder.setThreshold(failurePercentage.threshold()); | |
| } | |
| if (failurePercentage.enforcementPercentage() != null) { | |
| failurePercentageConfigBuilder.setEnforcementPercentage( | |
| failurePercentage.enforcementPercentage()); | |
| } | |
| if (failurePercentage.minimumHosts() != null) { | |
| failurePercentageConfigBuilder.setMinimumHosts(failurePercentage.minimumHosts()); | |
| } | |
| if (failurePercentage.requestVolume() != null) { | |
| failurePercentageConfigBuilder.setRequestVolume(failurePercentage.requestVolume()); | |
| } | |
| configBuilder.setFailurePercentageEjection(failurePercentageConfigBuilder.build()); |
But enforcement percentage is null, so the default percentage of 100 is applied:
grpc-java/util/src/main/java/io/grpc/util/OutlierDetectionLoadBalancer.java
Lines 1116 to 1121 in ed3bf6b
| public static class Builder { | |
| int threshold = 85; | |
| int enforcementPercentage = 100; | |
| int minimumHosts = 5; | |
| int requestVolume = 50; | |
The fix appears to be trivial. In EnvoyServerProtoData.java, change the check to:
if (!envoyOutlierDetection.hasEnforcingFailurePercentage()
|| envoyOutlierDetection.getEnforcingFailurePercentage().getValue() == 0) {
failurePercentageEjection = null;
} else {
// ...
Activity
ahmadmaaz commentedon Nov 6, 2026
Hi!
I would like to work on this if no one on the team has picked it up yet.
I will go with the fix suggested above, and add tests for the unset, explicit-zero, and non-zero cases.
Happy to have a PR up within a few days.