diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index 5b164c14ea..05dee80c6e 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -1369,7 +1369,6 @@ final class ManagedChannelImpl extends ManagedChannel implements "Resolved address: {0}, config={1}", servers, resolutionResult.getAttributes()); - ResolutionState lastResolutionStateCopy = lastResolutionState; if (lastResolutionState != ResolutionState.SUCCESS) { channelLogger.log(ChannelLogLevel.INFO, "Address resolved: {0}", servers); @@ -1457,14 +1456,7 @@ final class ManagedChannelImpl extends ManagedChannel implements .build()); if (!handleResult.isOk()) { - if (servers.isEmpty() && lastResolutionStateCopy == ResolutionState.SUCCESS) { - // lb doesn't expose that it needs address or not, because for some LB it is not - // deterministic. Assuming lb needs address if LB returns error when the address is - // empty and it is not the first resolution. - scheduleExponentialBackOffInSyncContext(); - } else { - handleErrorInSyncContext(handleResult.augmentDescription(resolver + " was used")); - } + handleErrorInSyncContext(handleResult.augmentDescription(resolver + " was used")); } } } diff --git a/core/src/test/java/io/grpc/internal/ServiceConfigErrorHandlingTest.java b/core/src/test/java/io/grpc/internal/ServiceConfigErrorHandlingTest.java index f81a4c5a73..7e61213f86 100644 --- a/core/src/test/java/io/grpc/internal/ServiceConfigErrorHandlingTest.java +++ b/core/src/test/java/io/grpc/internal/ServiceConfigErrorHandlingTest.java @@ -274,17 +274,19 @@ public class ServiceConfigErrorHandlingTest { assertThat(channel.getState(true)).isEqualTo(ConnectivityState.IDLE); reset(mockLoadBalancer); - Map ignoredServiceConfig = - parseJson("{\"loadBalancingConfig\": [{\"round_robin\": {}}]}"); - nameResolverFactory.nextRawServiceConfig.set(ignoredServiceConfig); nameResolverFactory.servers.clear(); // 2nd resolution nameResolverFactory.allResolved(); - // 2nd service config without address should be ignored + // 2nd service config without addresses + ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Status.class); verify(mockLoadBalancer, never()).handleResolvedAddresses(any(ResolvedAddresses.class)); - verify(mockLoadBalancer, never()).handleNameResolutionError(any(Status.class)); + verify(mockLoadBalancer).handleNameResolutionError(statusCaptor.capture()); + assertThat(statusCaptor.getValue().getCode()).isEqualTo(Status.Code.UNAVAILABLE); + assertThat(statusCaptor.getValue().getDescription()) + .contains("NameResolver returned no usable address."); + assertThat(channel.getState(true)).isEqualTo(ConnectivityState.TRANSIENT_FAILURE); assertWithMessage("Empty address should schedule NameResolver retry") .that(getNameResolverRefresh()) .isNotNull();