mirror of https://github.com/grpc/grpc-java.git
Make address resolution error use the default service config (#11577)
Fixes #11040.
This commit is contained in:
parent
50e442fea6
commit
fa26a8bc5e
|
|
@ -956,7 +956,15 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
// Must run in SynchronizationContext.
|
||||
void onConfigError() {
|
||||
if (configSelector.get() == INITIAL_PENDING_SELECTOR) {
|
||||
updateConfigSelector(null);
|
||||
// Apply Default Service Config if initial name resolution fails.
|
||||
if (defaultServiceConfig != null) {
|
||||
updateConfigSelector(defaultServiceConfig.getDefaultConfigSelector());
|
||||
lastServiceConfig = defaultServiceConfig;
|
||||
channelLogger.log(ChannelLogLevel.ERROR,
|
||||
"Initial Name Resolution error, using default service config");
|
||||
} else {
|
||||
updateConfigSelector(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ import io.grpc.IntegerMarshaller;
|
|||
import io.grpc.InternalChannelz;
|
||||
import io.grpc.InternalChannelz.ChannelStats;
|
||||
import io.grpc.InternalChannelz.ChannelTrace;
|
||||
import io.grpc.InternalChannelz.ChannelTrace.Event.Severity;
|
||||
import io.grpc.InternalConfigSelector;
|
||||
import io.grpc.InternalInstrumented;
|
||||
import io.grpc.LoadBalancer;
|
||||
|
|
@ -123,6 +124,7 @@ import io.grpc.internal.InternalSubchannel.TransportLogger;
|
|||
import io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder;
|
||||
import io.grpc.internal.ManagedChannelImplBuilder.FixedPortProvider;
|
||||
import io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder;
|
||||
import io.grpc.internal.ManagedChannelServiceConfig.MethodInfo;
|
||||
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
|
||||
import io.grpc.internal.TestUtils.MockClientTransportInfo;
|
||||
import io.grpc.stub.ClientCalls;
|
||||
|
|
@ -1127,6 +1129,55 @@ public class ManagedChannelImplTest {
|
|||
verifyNoMoreInteractions(mockLoadBalancer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addressResolutionError_noPriorNameResolution_usesDefaultServiceConfig()
|
||||
throws Exception {
|
||||
Map<String, Object> rawServiceConfig =
|
||||
parseConfig("{\"methodConfig\":[{"
|
||||
+ "\"name\":[{\"service\":\"service\"}],"
|
||||
+ "\"waitForReady\":true}]}");
|
||||
ManagedChannelServiceConfig managedChannelServiceConfig =
|
||||
createManagedChannelServiceConfig(rawServiceConfig, null);
|
||||
FakeNameResolverFactory nameResolverFactory =
|
||||
new FakeNameResolverFactory.Builder(expectedUri)
|
||||
.setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress)))
|
||||
.setResolvedAtStart(false)
|
||||
.build();
|
||||
nameResolverFactory.nextConfigOrError.set(
|
||||
ConfigOrError.fromConfig(managedChannelServiceConfig));
|
||||
channelBuilder.nameResolverFactory(nameResolverFactory);
|
||||
Map<String, Object> defaultServiceConfig =
|
||||
parseConfig("{\"methodConfig\":[{"
|
||||
+ "\"name\":[{\"service\":\"service\"}],"
|
||||
+ "\"waitForReady\":true}]}");
|
||||
channelBuilder.defaultServiceConfig(defaultServiceConfig);
|
||||
Status resolutionError = Status.UNAVAILABLE.withDescription("Resolution failed");
|
||||
channelBuilder.maxTraceEvents(10);
|
||||
createChannel();
|
||||
FakeNameResolverFactory.FakeNameResolver resolver = nameResolverFactory.resolvers.get(0);
|
||||
|
||||
resolver.listener.onError(resolutionError);
|
||||
|
||||
InternalConfigSelector configSelector = channel.getConfigSelector();
|
||||
ManagedChannelServiceConfig config =
|
||||
(ManagedChannelServiceConfig) configSelector.selectConfig(null).getConfig();
|
||||
MethodInfo methodConfig = config.getMethodConfig(method);
|
||||
assertThat(methodConfig.waitForReady).isTrue();
|
||||
timer.forwardNanos(1234);
|
||||
assertThat(getStats(channel).channelTrace.events).contains(new ChannelTrace.Event.Builder()
|
||||
.setDescription("Initial Name Resolution error, using default service config")
|
||||
.setSeverity(Severity.CT_ERROR)
|
||||
.setTimestampNanos(0)
|
||||
.build());
|
||||
|
||||
// Check that "lastServiceConfig" variable has been set above: a config resolution with the same
|
||||
// config simply gets ignored and not gets reassigned.
|
||||
resolver.resolved();
|
||||
timer.forwardNanos(1234);
|
||||
assertThat(getStats(channel).channelTrace.events.stream().filter(
|
||||
event -> event.description.equals("Service config changed")).count()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptor() throws Exception {
|
||||
final AtomicLong atomic = new AtomicLong();
|
||||
|
|
@ -4595,7 +4646,7 @@ public class ManagedChannelImplTest {
|
|||
int size = getStats(channel).channelTrace.events.size();
|
||||
assertThat(getStats(channel).channelTrace.events.get(size - 1))
|
||||
.isNotEqualTo(new ChannelTrace.Event.Builder()
|
||||
.setDescription("Using default service config")
|
||||
.setDescription("timer.forwardNanos(1234);")
|
||||
.setSeverity(ChannelTrace.Event.Severity.CT_INFO)
|
||||
.setTimestampNanos(timer.getTicker().read())
|
||||
.build());
|
||||
|
|
|
|||
Loading…
Reference in New Issue