Skip to content

Commit

Permalink
core: Clear ConfigSelector in panic mode
Browse files Browse the repository at this point in the history
If the failure is before the NameResolver has returned the first time,
RPCs would be queued waiting for service config. We don't want to use
the ConfigSelector, as we are trying to circumvent the NameResolver and
LoadBalancer.

Fixes #9257
  • Loading branch information
ejona86 committed Jun 15, 2022
1 parent b06942d commit d2b0538
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/src/main/java/io/grpc/internal/ManagedChannelImpl.java
Expand Up @@ -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);
}
Expand Down Expand Up @@ -1755,6 +1756,9 @@ final class NamesResolved implements Runnable {
@SuppressWarnings("ReferenceEquality")
@Override
public void run() {
if (ManagedChannelImpl.this.nameResolver != resolver) {
return;
}

List<EquivalentAddressGroup> servers = resolutionResult.getAddresses();
channelLogger.log(
Expand Down
34 changes: 34 additions & 0 deletions core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java
Expand Up @@ -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<String, Integer> 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")
Expand Down

0 comments on commit d2b0538

Please sign in to comment.