diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index b0d07efe254..bbd45cf34ca 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -887,6 +887,7 @@ public String toString() { } updateSubchannelPicker(new PanicSubchannelPicker()); + realChannel.updateConfigSelector(null); channelLogger.log(ChannelLogLevel.ERROR, "PANIC! Entering TRANSIENT_FAILURE"); channelStateManager.gotoState(TRANSIENT_FAILURE); } @@ -1755,6 +1756,9 @@ final class NamesResolved implements Runnable { @SuppressWarnings("ReferenceEquality") @Override public void run() { + if (ManagedChannelImpl.this.nameResolver != resolver) { + return; + } List servers = resolutionResult.getAddresses(); channelLogger.log( diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java index f47954e2215..3f3951a4524 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java @@ -2799,6 +2799,40 @@ public void run() { panicExpected = true; } + @Test + public void panic_atStart() { + final RuntimeException panicReason = new RuntimeException("Simulated NR exception"); + final NameResolver failingResolver = new NameResolver() { + @Override public String getServiceAuthority() { + return "fake-authority"; + } + + @Override public void start(Listener2 listener) { + throw panicReason; + } + + @Override public void shutdown() {} + }; + channelBuilder.nameResolverFactory(new NameResolver.Factory() { + @Override public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) { + return failingResolver; + } + + @Override public String getDefaultScheme() { + return "fakescheme"; + } + }); + createChannel(); + + // RPCs fail immediately + ClientCall call = + channel.newCall(method, CallOptions.DEFAULT.withoutWaitForReady()); + call.start(mockCallListener, new Metadata()); + executor.runDueTasks(); + verifyCallListenerClosed(mockCallListener, Status.Code.INTERNAL, panicReason); + panicExpected = true; + } + private void verifyPanicMode(Throwable cause) { panicExpected = true; @SuppressWarnings("unchecked")