xds: shut down EDS downstream LB policies when no usable endpoints received (#7452)

This commit is contained in:
Chengyuan Zhang 2020-09-24 15:08:05 -07:00 committed by GitHub
parent 2e411512be
commit 10b960ea5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 13 deletions

View File

@ -275,10 +275,8 @@ final class EdsLoadBalancer2 extends LoadBalancer {
locality, localityLbInfo.getLocalityWeight()); locality, localityLbInfo.getLocalityWeight());
} }
if (prioritizedLocalityWeights.isEmpty()) { if (prioritizedLocalityWeights.isEmpty()) {
lbHelper.helper.updateBalancingState( propagateResourceError(
TRANSIENT_FAILURE, Status.UNAVAILABLE.withDescription("No usable priority/locality/endpoint"));
new ErrorPicker(
Status.UNAVAILABLE.withDescription("No usable priority/locality/endpoint")));
return; return;
} }
if (lb == null) { if (lb == null) {
@ -310,15 +308,8 @@ final class EdsLoadBalancer2 extends LoadBalancer {
@Override @Override
public void onResourceDoesNotExist(String resourceName) { public void onResourceDoesNotExist(String resourceName) {
logger.log(XdsLogLevel.INFO, "Resource {0} is unavailable", resourceName); logger.log(XdsLogLevel.INFO, "Resource {0} is unavailable", resourceName);
if (lb != null) { propagateResourceError(
lb.shutdown(); Status.UNAVAILABLE.withDescription("Resource " + resourceName + " is unavailable"));
lb = null;
}
lbHelper.helper.updateBalancingState(
TRANSIENT_FAILURE,
new ErrorPicker(
Status.UNAVAILABLE.withDescription(
"Resource " + resourceName + " is unavailable")));
} }
@Override @Override
@ -330,6 +321,14 @@ final class EdsLoadBalancer2 extends LoadBalancer {
} }
} }
private void propagateResourceError(Status error) {
if (lb != null) {
lb.shutdown();
lb = null;
}
lbHelper.helper.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(error));
}
private final class DropHandlingLbHelper extends ForwardingLoadBalancerHelper { private final class DropHandlingLbHelper extends ForwardingLoadBalancerHelper {
private final Helper helper; private final Helper helper;
private List<DropOverload> dropPolicies = Collections.emptyList(); private List<DropOverload> dropPolicies = Collections.emptyList();

View File

@ -406,6 +406,27 @@ public class EdsLoadBalancer2Test {
.isEqualTo("No usable priority/locality/endpoint"); .isEqualTo("No usable priority/locality/endpoint");
} }
@Test
public void handleEndpointResource_shutDownExistingChildLbPoliciesIfNoUsableEndpoints() {
deliverSimpleClusterLoadAssignment(EDS_SERVICE_NAME);
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(downstreamBalancers);
assertThat(childBalancer.shutdown).isFalse();
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
LocalityLbEndpoints localityLbEndpoints1 =
buildLocalityLbEndpoints(1, 10, Collections.singletonMap(endpoint1, false));
xdsClient.deliverClusterLoadAssignment(
EDS_SERVICE_NAME, Collections.singletonMap(locality1, localityLbEndpoints1));
assertThat(childBalancer.shutdown).isTrue();
assertThat(currentState).isEqualTo(ConnectivityState.TRANSIENT_FAILURE);
PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
assertThat(result.getStatus().isOk()).isFalse();
assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
assertThat(result.getStatus().getDescription())
.isEqualTo("No usable priority/locality/endpoint");
}
@Test @Test
public void handleDrops() { public void handleDrops() {
FakeLoadBalancerProvider fakeRoundRobinProvider = new FakeLoadBalancerProvider("round_robin"); FakeLoadBalancerProvider fakeRoundRobinProvider = new FakeLoadBalancerProvider("round_robin");