1919import com .google .api .core .InternalApi ;
2020import com .google .api .gax .core .BackgroundResource ;
2121import com .google .api .gax .core .CredentialsProvider ;
22- import com .google .api .gax .core .ExecutorAsBackgroundResource ;
22+ import com .google .api .gax .core .ExecutorProvider ;
2323import com .google .api .gax .core .FixedCredentialsProvider ;
24- import com .google .api .gax .core .FixedExecutorProvider ;
2524import com .google .api .gax .grpc .InstantiatingGrpcChannelProvider ;
2625import com .google .api .gax .rpc .ClientContext ;
2726import com .google .auth .Credentials ;
3635import com .google .cloud .bigtable .data .v2 .stub .metrics .NoopMetricsProvider ;
3736import com .google .cloud .bigtable .gaxx .grpc .BigtableTransportChannelProvider ;
3837import com .google .cloud .bigtable .gaxx .grpc .ChannelPrimer ;
39- import com .google .common .collect .ImmutableList ;
4038import io .grpc .ManagedChannelBuilder ;
4139import io .grpc .opentelemetry .GrpcOpenTelemetry ;
4240import io .opentelemetry .api .OpenTelemetry ;
@@ -62,6 +60,9 @@ public class BigtableClientContext {
6260 @ Nullable private final OpenTelemetrySdk internalOpenTelemetry ;
6361 private final MetricsProvider metricsProvider ;
6462 private final ClientContext clientContext ;
63+ // the background executor shared for OTEL instances and monitoring client and all other
64+ // background tasks
65+ private final ExecutorProvider backgroundExecutorProvider ;
6566
6667 public static BigtableClientContext create (EnhancedBigtableStubSettings settings )
6768 throws IOException {
@@ -79,16 +80,12 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
7980
8081 String universeDomain = settings .getUniverseDomain ();
8182
82- boolean canAutoCloseExecutor = true ;
83+ boolean shouldAutoClose = settings . getBackgroundExecutorProvider (). shouldAutoClose () ;
8384 ScheduledExecutorService backgroundExecutor =
8485 settings .getBackgroundExecutorProvider ().getExecutor ();
85- if (settings .getBackgroundExecutorProvider () instanceof FixedExecutorProvider ) {
86- // if the background executor in the settings is already a FixedExecutorProvider,
87- // we can't assume that we can autoclose it and the life cycle should be managed
88- // by the application
89- canAutoCloseExecutor = false ;
90- }
91- FixedExecutorProvider executorProvider = FixedExecutorProvider .create (backgroundExecutor );
86+ // TODO: after gax change is merged, migrate to use gax's FixedExecutorProvider
87+ BigtableExecutorProvider executorProvider =
88+ BigtableExecutorProvider .create (backgroundExecutor , shouldAutoClose );
9289 builder .setBackgroundExecutorProvider (executorProvider );
9390
9491 // Set up OpenTelemetry
@@ -162,23 +159,16 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
162159 }
163160
164161 ClientContext clientContext = ClientContext .create (builder .build ());
165- if (canAutoCloseExecutor ) {
166- // Since we converted background executor to a FixedExecutorProvider, we need
167- // to add it back to the background resources, so it will be closed when we close the
168- // client context.
169- ImmutableList <BackgroundResource > backgroundResources =
170- ImmutableList .<BackgroundResource >builder ()
171- .addAll (clientContext .getBackgroundResources ())
172- .add (new ExecutorAsBackgroundResource (backgroundExecutor ))
173- .build ();
174- clientContext = clientContext .toBuilder ().setBackgroundResources (backgroundResources ).build ();
175- }
176162 if (channelPoolMetricsTracer != null ) {
177163 channelPoolMetricsTracer .start (clientContext .getExecutor ());
178164 }
179165
180166 return new BigtableClientContext (
181- clientContext , openTelemetry , internalOtel , settings .getMetricsProvider ());
167+ clientContext ,
168+ openTelemetry ,
169+ internalOtel ,
170+ settings .getMetricsProvider (),
171+ executorProvider );
182172 }
183173
184174 private static void configureGrpcOtel (
@@ -212,11 +202,13 @@ private BigtableClientContext(
212202 ClientContext clientContext ,
213203 @ Nullable OpenTelemetry openTelemetry ,
214204 @ Nullable OpenTelemetrySdk internalOtel ,
215- MetricsProvider metricsProvider ) {
205+ MetricsProvider metricsProvider ,
206+ ExecutorProvider backgroundExecutorProvider ) {
216207 this .clientContext = clientContext ;
217208 this .openTelemetry = openTelemetry ;
218209 this .internalOpenTelemetry = internalOtel ;
219210 this .metricsProvider = metricsProvider ;
211+ this .backgroundExecutorProvider = backgroundExecutorProvider ;
220212 }
221213
222214 public OpenTelemetry getOpenTelemetry () {
@@ -229,7 +221,11 @@ public ClientContext getClientContext() {
229221
230222 public BigtableClientContext withClientContext (ClientContext clientContext ) {
231223 return new BigtableClientContext (
232- clientContext , openTelemetry , internalOpenTelemetry , metricsProvider );
224+ clientContext ,
225+ openTelemetry ,
226+ internalOpenTelemetry ,
227+ metricsProvider ,
228+ backgroundExecutorProvider );
233229 }
234230
235231 public void close () throws Exception {
@@ -242,6 +238,9 @@ public void close() throws Exception {
242238 if (metricsProvider instanceof DefaultMetricsProvider && openTelemetry != null ) {
243239 ((OpenTelemetrySdk ) openTelemetry ).close ();
244240 }
241+ if (backgroundExecutorProvider .shouldAutoClose ()) {
242+ backgroundExecutorProvider .getExecutor ().shutdownNow ();
243+ }
245244 }
246245
247246 private static OpenTelemetry getOpenTelemetryFromMetricsProvider (
0 commit comments