Skip to content

Commit 785c5f9

Browse files
committed
Fixup: Change the fallback order to prefer custom metrics over app util
1 parent 4e9363a commit 785c5f9

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

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

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

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

409412
/**

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)