1717package io .grpc .cronet ;
1818
1919import static com .google .common .base .Preconditions .checkArgument ;
20+ import static com .google .common .base .Preconditions .checkNotNull ;
2021import static io .grpc .internal .GrpcUtil .DEFAULT_MAX_MESSAGE_SIZE ;
2122
2223import com .google .common .annotations .VisibleForTesting ;
@@ -73,6 +74,9 @@ public static CronetChannelBuilder forAddress(String name, int port) {
7374 throw new UnsupportedOperationException ("call forAddress(String, int, CronetEngine) instead" );
7475 }
7576
77+ @ Nullable
78+ private ScheduledExecutorService scheduledExecutorService ;
79+
7680 private final CronetEngine cronetEngine ;
7781
7882 private boolean alwaysUsePut = false ;
@@ -161,12 +165,30 @@ public final CronetChannelBuilder setTrafficStatsUid(int uid) {
161165 return this ;
162166 }
163167
168+ /**
169+ * Provides a custom scheduled executor service.
170+ *
171+ * <p>It's an optional parameter. If the user has not provided a scheduled executor service when
172+ * the channel is built, the builder will use a static cached thread pool.
173+ *
174+ * @return this
175+ *
176+ * @since 1.12.0
177+ */
178+ public final CronetChannelBuilder scheduledExecutorService (
179+ ScheduledExecutorService scheduledExecutorService ) {
180+ this .scheduledExecutorService =
181+ checkNotNull (scheduledExecutorService , "scheduledExecutorService" );
182+ return this ;
183+ }
184+
164185 @ Override
165186 protected final ClientTransportFactory buildTransportFactory () {
166187 return new CronetTransportFactory (
167188 new TaggingStreamFactory (
168189 cronetEngine , trafficStatsTagSet , trafficStatsTag , trafficStatsUidSet , trafficStatsUid ),
169190 MoreExecutors .directExecutor (),
191+ scheduledExecutorService ,
170192 maxMessageSize ,
171193 alwaysUsePut ,
172194 transportTracerFactory .create ());
@@ -180,20 +202,24 @@ protected Attributes getNameResolverParams() {
180202
181203 @ VisibleForTesting
182204 static class CronetTransportFactory implements ClientTransportFactory {
183- private final ScheduledExecutorService timeoutService =
184- SharedResourceHolder .get (GrpcUtil .TIMER_SERVICE );
205+ private final ScheduledExecutorService timeoutService ;
185206 private final Executor executor ;
186207 private final int maxMessageSize ;
187208 private final boolean alwaysUsePut ;
188209 private final StreamBuilderFactory streamFactory ;
189210 private final TransportTracer transportTracer ;
211+ private final boolean usingSharedScheduler ;
190212
191213 private CronetTransportFactory (
192214 StreamBuilderFactory streamFactory ,
193215 Executor executor ,
216+ @ Nullable ScheduledExecutorService timeoutService ,
194217 int maxMessageSize ,
195218 boolean alwaysUsePut ,
196219 TransportTracer transportTracer ) {
220+ usingSharedScheduler = timeoutService == null ;
221+ this .timeoutService = usingSharedScheduler
222+ ? SharedResourceHolder .get (GrpcUtil .TIMER_SERVICE ) : timeoutService ;
197223 this .maxMessageSize = maxMessageSize ;
198224 this .alwaysUsePut = alwaysUsePut ;
199225 this .streamFactory = streamFactory ;
@@ -216,7 +242,9 @@ public ScheduledExecutorService getScheduledExecutorService() {
216242
217243 @ Override
218244 public void close () {
219- SharedResourceHolder .release (GrpcUtil .TIMER_SERVICE , timeoutService );
245+ if (usingSharedScheduler ) {
246+ SharedResourceHolder .release (GrpcUtil .TIMER_SERVICE , timeoutService );
247+ }
220248 }
221249 }
222250
0 commit comments