Skip to content

Commit 63c5bf3

Browse files
committed
Fixup: Change the fallback order to prefer custom metrics over app util
1 parent 9d2594c commit 63c5bf3

2 files changed

Lines changed: 45 additions & 6 deletions

File tree

xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,18 +393,21 @@ public void onLoadReport(MetricReport report) {
393393
}
394394

395395
/**
396-
* Returns the utilization value computed from the specified metric names. If the application
397-
* utilization is present and valid, it is returned. Otherwise, the maximum of the custom
398-
* metrics specified is returned. If none of the custom metrics are present, the CPU
396+
* Returns the utilization value computed from the specified metric names. If the custom
397+
* metrics are present and valid, the maximum of the custom metrics is returned. Otherwise,
398+
* if application utilization is > 0, it is returned. If neither are present, the CPU
399399
* utilization is returned.
400400
*/
401401
private double getUtilization(MetricReport report, ImmutableList<String> metricNames) {
402+
OptionalDouble customUtil = getCustomMetricUtilization(report, metricNames);
403+
if (customUtil.isPresent()) {
404+
return customUtil.getAsDouble();
405+
}
402406
double appUtil = report.getApplicationUtilization();
403407
if (appUtil > 0) {
404408
return appUtil;
405409
}
406-
return getCustomMetricUtilization(report, metricNames)
407-
.orElse(report.getCpuUtilization());
410+
return report.getCpuUtilization();
408411
}
409412

410413
/**

xds/src/test/java/io/grpc/xds/WeightedRoundRobinLoadBalancerTest.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,7 @@ public void metricWithRealChannel() throws Exception {
13341334

13351335

13361336
@Test
1337-
public void customMetric_priority_appUtilStillPreferred() {
1337+
public void customMetric_priority_overAppUtil() {
13381338
weightedConfig = WeightedRoundRobinLoadBalancerConfig.newBuilder().setBlackoutPeriodNanos(0)
13391339
.setMetricNamesForComputingUtilization(ImmutableList.of("named_metrics.cost")).build();
13401340
wrr = new WeightedRoundRobinLoadBalancer(helper, fakeClock.getDeadlineTicker());
@@ -1359,6 +1359,42 @@ public void customMetric_priority_appUtilStillPreferred() {
13591359
MetricReport report = InternalCallMetricRecorder.createMetricReport(0.1, 0.8, 0.1, 1, 0,
13601360
new HashMap<>(), new HashMap<>(), namedMetrics);
13611361
listener.onLoadReport(report);
1362+
// Custom metrics now take priority over app_util
1363+
// qps=1, util=0.5 -> weight=2.0
1364+
fakeClock.forwardTime(1100, TimeUnit.MILLISECONDS);
1365+
verify(mockMetricRecorder).recordDoubleHistogram(
1366+
argThat(instr -> instr.getName().equals("grpc.lb.wrr.endpoint_weights")), eq(2.0), any(),
1367+
any());
1368+
}
1369+
1370+
@Test
1371+
public void customMetric_invalid_fallbackToAppUtil() {
1372+
weightedConfig = WeightedRoundRobinLoadBalancerConfig.newBuilder().setBlackoutPeriodNanos(0)
1373+
.setMetricNamesForComputingUtilization(ImmutableList.of("named_metrics.cost")).build();
1374+
wrr = new WeightedRoundRobinLoadBalancer(helper, fakeClock.getDeadlineTicker());
1375+
1376+
syncContext.execute(
1377+
() -> wrr.acceptResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers)
1378+
.setLoadBalancingPolicyConfig(weightedConfig).setAttributes(affinity).build()));
1379+
1380+
Iterator<Subchannel> it = subchannels.values().iterator();
1381+
Subchannel readySubchannel = it.next();
1382+
getSubchannelStateListener(readySubchannel)
1383+
.onSubchannelState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
1384+
1385+
WeightedChildLbState weightedChild =
1386+
(WeightedChildLbState) wrr.getChildLbStates().iterator().next();
1387+
WeightedChildLbState.OrcaReportListener listener = weightedChild.getOrCreateOrcaListener(
1388+
weightedConfig.errorUtilizationPenalty, weightedConfig.metricNamesForComputingUtilization);
1389+
1390+
// custom metric is NaN, App util = 0.8
1391+
Map<String, Double> namedMetrics = new HashMap<>();
1392+
namedMetrics.put("cost", Double.NaN);
1393+
MetricReport report = InternalCallMetricRecorder.createMetricReport(0.1, 0.8, 0.1, 1, 0,
1394+
new HashMap<>(), new HashMap<>(), namedMetrics);
1395+
listener.onLoadReport(report);
1396+
1397+
// Should fallback to App Util (0.8)
13621398
// qps=1, util=0.8 -> weight=1.25
13631399
fakeClock.forwardTime(1100, TimeUnit.MILLISECONDS);
13641400
verify(mockMetricRecorder).recordDoubleHistogram(

0 commit comments

Comments
 (0)