Skip to content

Commit 39c2646

Browse files
authored
xds: least_request LB to use acceptResolvedAddresses() (#9616)
This is part of a migration to move all LBs away from using handleResolvedAddresses().
1 parent a65ecef commit 39c2646

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ final class LeastRequestLoadBalancer extends LoadBalancer {
8888
}
8989

9090
@Override
91-
public void handleResolvedAddresses(ResolvedAddresses resolvedAddresses) {
91+
public boolean acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
92+
if (resolvedAddresses.getAddresses().isEmpty()) {
93+
handleNameResolutionError(Status.UNAVAILABLE.withDescription(
94+
"NameResolver returned no usable address. addrs=" + resolvedAddresses.getAddresses()
95+
+ ", attrs=" + resolvedAddresses.getAttributes()));
96+
return false;
97+
}
9298
LeastRequestConfig config =
9399
(LeastRequestConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
94100
// Config may be null if least_request is used outside xDS
@@ -146,6 +152,8 @@ public void onSubchannelState(ConnectivityStateInfo state) {
146152
for (Subchannel removedSubchannel : removedSubchannels) {
147153
shutdownSubchannel(removedSubchannel);
148154
}
155+
156+
return true;
149157
}
150158

151159
@Override

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

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ public void tearDown() throws Exception {
155155
@Test
156156
public void pickAfterResolved() throws Exception {
157157
final Subchannel readySubchannel = subchannels.values().iterator().next();
158-
loadBalancer.handleResolvedAddresses(
158+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
159159
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(affinity).build());
160+
assertThat(addressesAccepted).isTrue();
160161
deliverSubchannelState(readySubchannel, ConnectivityStateInfo.forNonError(READY));
161162

162163
verify(mockHelper, times(3)).createSubchannel(createArgsCaptor.capture());
@@ -206,9 +207,10 @@ public void pickAfterResolvedUpdatedHosts() throws Exception {
206207

207208
InOrder inOrder = inOrder(mockHelper);
208209

209-
loadBalancer.handleResolvedAddresses(
210+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
210211
ResolvedAddresses.newBuilder().setAddresses(currentServers).setAttributes(affinity)
211212
.build());
213+
assertThat(addressesAccepted).isTrue();
212214

213215
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
214216

@@ -228,8 +230,9 @@ public void pickAfterResolvedUpdatedHosts() throws Exception {
228230
// This time with Attributes
229231
List<EquivalentAddressGroup> latestServers = Lists.newArrayList(oldEag2, newEag);
230232

231-
loadBalancer.handleResolvedAddresses(
233+
addressesAccepted = loadBalancer.acceptResolvedAddresses(
232234
ResolvedAddresses.newBuilder().setAddresses(latestServers).setAttributes(affinity).build());
235+
assertThat(addressesAccepted).isTrue();
233236

234237
verify(newSubchannel, times(1)).requestConnection();
235238
verify(oldSubchannel, times(1)).updateAddresses(Arrays.asList(oldEag2));
@@ -247,25 +250,16 @@ public void pickAfterResolvedUpdatedHosts() throws Exception {
247250
picker = pickerCaptor.getValue();
248251
assertThat(getList(picker)).containsExactly(oldSubchannel, newSubchannel);
249252

250-
// test going from non-empty to empty
251-
loadBalancer.handleResolvedAddresses(
252-
ResolvedAddresses.newBuilder()
253-
.setAddresses(Collections.<EquivalentAddressGroup>emptyList())
254-
.setAttributes(affinity)
255-
.build());
256-
257-
inOrder.verify(mockHelper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
258-
assertEquals(PickResult.withNoResult(), pickerCaptor.getValue().pickSubchannel(mockArgs));
259-
260253
verifyNoMoreInteractions(mockHelper);
261254
}
262255

263256
@Test
264257
public void pickAfterStateChange() throws Exception {
265258
InOrder inOrder = inOrder(mockHelper);
266-
loadBalancer.handleResolvedAddresses(
259+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
267260
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
268261
.build());
262+
assertThat(addressesAccepted).isTrue();
269263
Subchannel subchannel = loadBalancer.getSubchannels().iterator().next();
270264
Ref<ConnectivityStateInfo> subchannelStateInfo = subchannel.getAttributes().get(
271265
STATE_INFO);
@@ -305,9 +299,10 @@ public void pickAfterConfigChange() {
305299
final LeastRequestConfig oldConfig = new LeastRequestConfig(4);
306300
final LeastRequestConfig newConfig = new LeastRequestConfig(6);
307301
final Subchannel readySubchannel = subchannels.values().iterator().next();
308-
loadBalancer.handleResolvedAddresses(
302+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
309303
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(affinity)
310304
.setLoadBalancingPolicyConfig(oldConfig).build());
305+
assertThat(addressesAccepted).isTrue();
311306
deliverSubchannelState(readySubchannel, ConnectivityStateInfo.forNonError(READY));
312307
verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
313308
verify(mockHelper, times(2))
@@ -317,9 +312,10 @@ public void pickAfterConfigChange() {
317312
pickerCaptor.getValue().pickSubchannel(mockArgs);
318313
verify(mockRandom, times(oldConfig.choiceCount)).nextInt(1);
319314

320-
loadBalancer.handleResolvedAddresses(
315+
addressesAccepted = loadBalancer.acceptResolvedAddresses(
321316
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(affinity)
322317
.setLoadBalancingPolicyConfig(newConfig).build());
318+
assertThat(addressesAccepted).isTrue();
323319
verify(mockHelper, times(3))
324320
.updateBalancingState(any(ConnectivityState.class), pickerCaptor.capture());
325321

@@ -332,9 +328,10 @@ public void pickAfterConfigChange() {
332328
@Test
333329
public void ignoreShutdownSubchannelStateChange() {
334330
InOrder inOrder = inOrder(mockHelper);
335-
loadBalancer.handleResolvedAddresses(
331+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
336332
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
337333
.build());
334+
assertThat(addressesAccepted).isTrue();
338335
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), isA(EmptyPicker.class));
339336

340337
loadBalancer.shutdown();
@@ -351,9 +348,10 @@ public void ignoreShutdownSubchannelStateChange() {
351348
@Test
352349
public void stayTransientFailureUntilReady() {
353350
InOrder inOrder = inOrder(mockHelper);
354-
loadBalancer.handleResolvedAddresses(
351+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
355352
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
356353
.build());
354+
assertThat(addressesAccepted).isTrue();
357355

358356
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), isA(EmptyPicker.class));
359357

@@ -389,9 +387,10 @@ public void stayTransientFailureUntilReady() {
389387
@Test
390388
public void refreshNameResolutionWhenSubchannelConnectionBroken() {
391389
InOrder inOrder = inOrder(mockHelper);
392-
loadBalancer.handleResolvedAddresses(
390+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
393391
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
394392
.build());
393+
assertThat(addressesAccepted).isTrue();
395394

396395
verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
397396
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), isA(EmptyPicker.class));
@@ -419,10 +418,11 @@ public void refreshNameResolutionWhenSubchannelConnectionBroken() {
419418
public void pickerLeastRequest() throws Exception {
420419
int choiceCount = 2;
421420
// This should add inFlight counters to all subchannels.
422-
loadBalancer.handleResolvedAddresses(
421+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
423422
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
424423
.setLoadBalancingPolicyConfig(new LeastRequestConfig(choiceCount))
425424
.build());
425+
assertThat(addressesAccepted).isTrue();
426426

427427
assertEquals(3, loadBalancer.getSubchannels().size());
428428

@@ -505,10 +505,11 @@ public void nameResolutionErrorWithNoChannels() throws Exception {
505505
public void nameResolutionErrorWithActiveChannels() throws Exception {
506506
int choiceCount = 8;
507507
final Subchannel readySubchannel = subchannels.values().iterator().next();
508-
loadBalancer.handleResolvedAddresses(
508+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
509509
ResolvedAddresses.newBuilder()
510510
.setLoadBalancingPolicyConfig(new LeastRequestConfig(choiceCount))
511511
.setAddresses(servers).setAttributes(affinity).build());
512+
assertThat(addressesAccepted).isTrue();
512513
deliverSubchannelState(readySubchannel, ConnectivityStateInfo.forNonError(READY));
513514
loadBalancer.handleNameResolutionError(Status.NOT_FOUND.withDescription("nameResolutionError"));
514515

@@ -538,9 +539,10 @@ public void subchannelStateIsolation() throws Exception {
538539
Subchannel sc2 = subchannelIterator.next();
539540
Subchannel sc3 = subchannelIterator.next();
540541

541-
loadBalancer.handleResolvedAddresses(
542+
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
542543
ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
543544
.build());
545+
assertThat(addressesAccepted).isTrue();
544546
verify(sc1, times(1)).requestConnection();
545547
verify(sc2, times(1)).requestConnection();
546548
verify(sc3, times(1)).requestConnection();
@@ -613,6 +615,15 @@ public void internalPickerComparisons() {
613615
assertFalse(ready5.isEquivalentTo(ready6));
614616
}
615617

618+
@Test
619+
public void emptyAddresses() {
620+
assertThat(loadBalancer.acceptResolvedAddresses(
621+
ResolvedAddresses.newBuilder()
622+
.setAddresses(Collections.<EquivalentAddressGroup>emptyList())
623+
.setAttributes(affinity)
624+
.build())).isFalse();
625+
}
626+
616627
private static List<Subchannel> getList(SubchannelPicker picker) {
617628
return picker instanceof ReadyPicker ? ((ReadyPicker) picker).getList() :
618629
Collections.<Subchannel>emptyList();

0 commit comments

Comments
 (0)