diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index 45819954473..9dff90855cd 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -145,12 +145,17 @@ final class ManagedChannelImpl extends ManagedChannel implements private static final ManagedChannelServiceConfig EMPTY_SERVICE_CONFIG = ManagedChannelServiceConfig.empty(); - private static final InternalConfigSelector INITIAL_PENDING_SELECTOR = + static final InternalConfigSelector INITIAL_PENDING_SELECTOR = new InternalConfigSelector() { @Override public Result selectConfig(PickSubchannelArgs args) { throw new IllegalStateException("Resolution is pending"); } + + @Override + public String toString() { + return "Resolution is pending"; + } }; private static final LoadBalancer.PickDetailsConsumer NOOP_PICK_DETAILS_CONSUMER = new LoadBalancer.PickDetailsConsumer() {}; @@ -931,9 +936,12 @@ public void run() { } // Must run in SynchronizationContext. - void updateConfigSelector(@Nullable InternalConfigSelector config) { + void updateConfigSelector(@Nullable InternalConfigSelector newConfig) { InternalConfigSelector prevConfig = configSelector.get(); - configSelector.set(config); + configSelector.set(newConfig); + channelLogger.log(ChannelLogLevel.INFO, + "Current config is replaced with new config. prevConfig={0}, newConfig={1}", + prevConfig, newConfig); if (prevConfig == INITIAL_PENDING_SELECTOR && pendingCalls != null) { for (RealChannel.PendingCall pendingCall : pendingCalls) { pendingCall.reprocess(); diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelServiceConfig.java b/core/src/main/java/io/grpc/internal/ManagedChannelServiceConfig.java index e5512dc8df4..7b5a7d884f8 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelServiceConfig.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelServiceConfig.java @@ -402,7 +402,7 @@ static final class ServiceConfigConvertedSelector extends InternalConfigSelector final ManagedChannelServiceConfig config; /** Converts the service config to config selector. */ - private ServiceConfigConvertedSelector(ManagedChannelServiceConfig config) { + ServiceConfigConvertedSelector(ManagedChannelServiceConfig config) { this.config = config; } @@ -412,5 +412,13 @@ public Result selectConfig(PickSubchannelArgs args) { .setConfig(config) .build(); } + + @Override + public String toString() { + return "ServiceConfigConvertedSelector{" + + "config=" + + config + + '}'; + } } } diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java index 21ccf1095df..47ac7470ff1 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java @@ -85,6 +85,7 @@ import io.grpc.InternalChannelz; import io.grpc.InternalChannelz.ChannelStats; import io.grpc.InternalChannelz.ChannelTrace; +import io.grpc.InternalChannelz.ChannelTrace.Event; import io.grpc.InternalChannelz.ChannelTrace.Event.Severity; import io.grpc.InternalConfigSelector; import io.grpc.InternalInstrumented; @@ -1208,6 +1209,14 @@ public void addressResolutionError_noPriorNameResolution_usesDefaultServiceConfi .isEmpty(); } + @Test + public void testToStringForInternalConfigSelector() { + String expected = "Resolution is pending"; + String actual = ManagedChannelImpl.INITIAL_PENDING_SELECTOR.toString(); + // Assert that the actual string equals the expected string + assertEquals("toString() should return 'Resolution is pending'", expected, actual); + } + @Test public void interceptor() throws Exception { final AtomicLong atomic = new AtomicLong(); @@ -3273,7 +3282,7 @@ public void channelTracing_nameResolvedEvent_zeorAndNonzeroBackends() throws Exc Arrays.asList(new SocketAddress() {}, new SocketAddress() {})))) .build(); nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult1); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize); + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); prevSize = getStats(channel).channelTrace.events.size(); nameResolverFactory.resolvers.get(0).listener.onError(Status.INTERNAL); @@ -3290,7 +3299,7 @@ public void channelTracing_nameResolvedEvent_zeorAndNonzeroBackends() throws Exc Arrays.asList(new SocketAddress() {}, new SocketAddress() {})))) .build(); nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult2); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 2); } @Test @@ -3314,7 +3323,7 @@ public void channelTracing_nameResolvedEvent_zeorAndNonzeroBackends_usesListener channel.syncContext.execute( () -> nameResolverFactory.resolvers.get(0).listener.onResult2(resolutionResult1)); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize); + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); prevSize = getStats(channel).channelTrace.events.size(); channel.syncContext.execute(() -> @@ -3340,7 +3349,7 @@ public void channelTracing_nameResolvedEvent_zeorAndNonzeroBackends_usesListener .build(); channel.syncContext.execute( () -> nameResolverFactory.resolvers.get(0).listener.onResult2(resolutionResult2)); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 2); } @Test @@ -3366,8 +3375,13 @@ public void channelTracing_serviceConfigChange() throws Exception { .setServiceConfig(ConfigOrError.fromConfig(mcsc1)) .build(); nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult1); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); - assertThat(getStats(channel).channelTrace.events.get(prevSize)) + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 2); + + Event configEvent = getStats(channel).channelTrace.events.get(prevSize); + + assertThat(configEvent.description) + .contains("Current config is replaced with new config. prevConfig="); + assertThat(getStats(channel).channelTrace.events.get(prevSize + 1)) .isEqualTo(new ChannelTrace.Event.Builder() .setDescription("Service config changed") .setSeverity(ChannelTrace.Event.Severity.CT_INFO) @@ -3382,7 +3396,7 @@ public void channelTracing_serviceConfigChange() throws Exception { .setServiceConfig(ConfigOrError.fromConfig(mcsc1)) .build(); nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult2); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize); + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); prevSize = getStats(channel).channelTrace.events.size(); timer.forwardNanos(1234); @@ -3393,8 +3407,8 @@ public void channelTracing_serviceConfigChange() throws Exception { .setServiceConfig(ConfigOrError.fromConfig(ManagedChannelServiceConfig.empty())) .build(); nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult3); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); - assertThat(getStats(channel).channelTrace.events.get(prevSize)) + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 2); + assertThat(getStats(channel).channelTrace.events.get(prevSize + 1)) .isEqualTo(new ChannelTrace.Event.Builder() .setDescription("Service config changed") .setSeverity(ChannelTrace.Event.Severity.CT_INFO) @@ -3427,8 +3441,8 @@ public void channelTracing_serviceConfigChange_usesListener2OnResult2() throws E channel.syncContext.execute(() -> nameResolverFactory.resolvers.get(0).listener.onResult2(resolutionResult1)); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); - assertThat(getStats(channel).channelTrace.events.get(prevSize)) + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 2); + assertThat(getStats(channel).channelTrace.events.get(prevSize + 1)) .isEqualTo(new ChannelTrace.Event.Builder() .setDescription("Service config changed") .setSeverity(ChannelTrace.Event.Severity.CT_INFO) @@ -3444,7 +3458,7 @@ public void channelTracing_serviceConfigChange_usesListener2OnResult2() throws E .build(); channel.syncContext.execute(() -> nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult2)); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize); + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); prevSize = getStats(channel).channelTrace.events.size(); timer.forwardNanos(1234); @@ -3456,8 +3470,8 @@ public void channelTracing_serviceConfigChange_usesListener2OnResult2() throws E .build(); channel.syncContext.execute(() -> nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult3)); - assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1); - assertThat(getStats(channel).channelTrace.events.get(prevSize)) + assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 2); + assertThat(getStats(channel).channelTrace.events.get(prevSize + 1)) .isEqualTo(new ChannelTrace.Event.Builder() .setDescription("Service config changed") .setSeverity(ChannelTrace.Event.Severity.CT_INFO) diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelServiceConfigTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelServiceConfigTest.java index 493714dfd41..393f04ad25b 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelServiceConfigTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelServiceConfigTest.java @@ -20,6 +20,7 @@ import static io.grpc.MethodDescriptor.MethodType.UNARY; import static io.grpc.Status.Code.UNAVAILABLE; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; @@ -31,6 +32,7 @@ import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.internal.ManagedChannelServiceConfig.MethodInfo; +import io.grpc.internal.ManagedChannelServiceConfig.ServiceConfigConvertedSelector; import io.grpc.testing.TestMethodDescriptors; import java.util.Collections; import java.util.Map; @@ -296,6 +298,26 @@ public void retryConfig_AllowPerAttemptRecvTimeoutZero() { .isNotNull(); } + @Test + public void testToStringForServiceConfigConvertedSelector() { + Map name = ImmutableMap.of("service", "service1", "method", "method1"); + Map methodConfig = ImmutableMap.of( + "name", ImmutableList.of(name), "timeout", "1.234s"); + Map rawServiceConfig = + ImmutableMap.of("methodConfig", ImmutableList.of(methodConfig)); + ManagedChannelServiceConfig serviceConfig = + ManagedChannelServiceConfig.fromServiceConfig(rawServiceConfig, false, 0, 0, null); + ServiceConfigConvertedSelector selector = new ServiceConfigConvertedSelector(serviceConfig); + // Assert the toString method contains the config/structure and other details with data + assertTrue(selector.toString().contains("ServiceConfigConvertedSelector{")); + assertTrue(selector.toString().contains("config")); + assertTrue(selector.toString().contains("ManagedChannelServiceConfig{")); + assertTrue(selector.toString().contains("defaultMethodConfig")); + assertTrue(selector.toString().contains("serviceMethodMap")); + assertTrue(selector.toString().contains("service1/method1")); + assertTrue(selector.toString().contains("serviceMap")); + } + private static MethodDescriptor methodForName(String service, String method) { return MethodDescriptor.newBuilder() .setFullMethodName(service + "/" + method)