diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index bbd45cf34c..00e9fb81a6 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -621,10 +621,12 @@ final class ManagedChannelImpl extends ManagedChannel implements this.executor = checkNotNull(executorPool.getObject(), "executor"); this.originalChannelCreds = builder.channelCredentials; this.originalTransportFactory = clientTransportFactory; + this.offloadExecutorHolder = + new ExecutorHolder(checkNotNull(builder.offloadExecutorPool, "offloadExecutorPool")); this.transportFactory = new CallCredentialsApplyingTransportFactory( - clientTransportFactory, builder.callCredentials, this.executor); + clientTransportFactory, builder.callCredentials, this.offloadExecutorHolder); this.oobTransportFactory = new CallCredentialsApplyingTransportFactory( - clientTransportFactory, null, this.executor); + clientTransportFactory, null, this.offloadExecutorHolder); this.scheduledExecutor = new RestrictedScheduledExecutor(transportFactory.getScheduledExecutorService()); maxTraceEvents = builder.maxTraceEvents; @@ -636,9 +638,6 @@ final class ManagedChannelImpl extends ManagedChannel implements builder.proxyDetector != null ? builder.proxyDetector : GrpcUtil.DEFAULT_PROXY_DETECTOR; this.retryEnabled = builder.retryEnabled; this.loadBalancerFactory = new AutoConfiguredLoadBalancerFactory(builder.defaultLbPolicy); - this.offloadExecutorHolder = - new ExecutorHolder( - checkNotNull(builder.offloadExecutorPool, "offloadExecutorPool")); this.nameResolverRegistry = builder.nameResolverRegistry; ScParser serviceConfigParser = new ScParser( @@ -654,14 +653,7 @@ final class ManagedChannelImpl extends ManagedChannel implements .setScheduledExecutorService(scheduledExecutor) .setServiceConfigParser(serviceConfigParser) .setChannelLogger(channelLogger) - .setOffloadExecutor( - // Avoid creating the offloadExecutor until it is first used - new Executor() { - @Override - public void execute(Runnable command) { - offloadExecutorHolder.getExecutor().execute(command); - } - }) + .setOffloadExecutor(this.offloadExecutorHolder) .build(); this.authorityOverride = builder.authorityOverride; this.nameResolverFactory = builder.nameResolverFactory; @@ -2219,8 +2211,10 @@ final class ManagedChannelImpl extends ManagedChannel implements /** * Lazily request for Executor from an executor pool. + * Also act as an Executor directly to simply run a cmd */ - private static final class ExecutorHolder { + @VisibleForTesting + static final class ExecutorHolder implements Executor { private final ObjectPool pool; private Executor executor; @@ -2240,6 +2234,11 @@ final class ManagedChannelImpl extends ManagedChannel implements executor = pool.returnObject(executor); } } + + @Override + public void execute(Runnable command) { + getExecutor().execute(command); + } } private static final class RestrictedScheduledExecutor implements ScheduledExecutorService { diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java index 3f3951a452..b5c8ca0c98 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java @@ -2396,9 +2396,12 @@ public class ManagedChannelImplTest { updateBalancingStateSafely(helper, READY, mockPicker); executor.runDueTasks(); ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(null); + ArgumentCaptor executorArgumentCaptor = ArgumentCaptor.forClass(null); ArgumentCaptor applierCaptor = ArgumentCaptor.forClass(null); verify(creds).applyRequestMetadata(infoCaptor.capture(), - same(executor.getScheduledExecutorService()), applierCaptor.capture()); + executorArgumentCaptor.capture(), applierCaptor.capture()); + assertSame(offloadExecutor, + ((ManagedChannelImpl.ExecutorHolder) executorArgumentCaptor.getValue()).getExecutor()); assertEquals("testValue", testKey.get(credsApplyContexts.poll())); assertEquals(AUTHORITY, infoCaptor.getValue().getAuthority()); assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel()); @@ -2423,7 +2426,9 @@ public class ManagedChannelImplTest { call.start(mockCallListener, new Metadata()); verify(creds, times(2)).applyRequestMetadata(infoCaptor.capture(), - same(executor.getScheduledExecutorService()), applierCaptor.capture()); + executorArgumentCaptor.capture(), applierCaptor.capture()); + assertSame(offloadExecutor, + ((ManagedChannelImpl.ExecutorHolder) executorArgumentCaptor.getValue()).getExecutor()); assertEquals("testValue", testKey.get(credsApplyContexts.poll())); assertEquals(AUTHORITY, infoCaptor.getValue().getAuthority()); assertEquals(SecurityLevel.NONE, infoCaptor.getValue().getSecurityLevel());