Skip to content

Commit e27dbe5

Browse files
perf: remove custom transport executor (#2366)
* perf: remove custom transport executor Remove the custom executor provider that is set on the underlying generated clients and instead use the internal core gRPC executor provider. The latter is a shared executor provider for all gRPC channels that creates threads on demand. This prevents the creation of unnecessary threads at startup, and can reduce overall thread usage for applications that create multiple Spanner instances during their lifetime. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent b02f584 commit e27dbe5

File tree

5 files changed

+30
-253
lines changed

5 files changed

+30
-253
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java

-68
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.google.api.core.InternalApi;
2424
import com.google.api.core.NanoClock;
2525
import com.google.api.gax.core.CredentialsProvider;
26-
import com.google.api.gax.core.ExecutorProvider;
2726
import com.google.api.gax.core.GaxProperties;
2827
import com.google.api.gax.grpc.GaxGrpcProperties;
2928
import com.google.api.gax.grpc.GrpcCallContext;
@@ -185,7 +184,6 @@
185184
import java.nio.charset.StandardCharsets;
186185
import java.util.Comparator;
187186
import java.util.HashMap;
188-
import java.util.LinkedList;
189187
import java.util.List;
190188
import java.util.Map;
191189
import java.util.Map.Entry;
@@ -200,8 +198,6 @@
200198
import java.util.concurrent.Executors;
201199
import java.util.concurrent.Future;
202200
import java.util.concurrent.ScheduledExecutorService;
203-
import java.util.concurrent.ScheduledThreadPoolExecutor;
204-
import java.util.concurrent.ThreadFactory;
205201
import java.util.concurrent.TimeUnit;
206202
import java.util.stream.Collectors;
207203
import java.util.stream.Stream;
@@ -211,53 +207,6 @@
211207
/** Implementation of Cloud Spanner remote calls using Gapic libraries. */
212208
@InternalApi
213209
public class GapicSpannerRpc implements SpannerRpc {
214-
215-
/**
216-
* {@link ExecutorProvider} that keeps track of the executors that are created and shuts these
217-
* down when the {@link SpannerRpc} is closed.
218-
*/
219-
private static final class ManagedInstantiatingExecutorProvider implements ExecutorProvider {
220-
221-
// 4 Gapic clients * 4 channels per client.
222-
private static final int DEFAULT_MIN_THREAD_COUNT = 16;
223-
private final List<ScheduledExecutorService> executors = new LinkedList<>();
224-
private final ThreadFactory threadFactory;
225-
226-
private ManagedInstantiatingExecutorProvider(ThreadFactory threadFactory) {
227-
this.threadFactory = threadFactory;
228-
}
229-
230-
@Override
231-
public boolean shouldAutoClose() {
232-
return false;
233-
}
234-
235-
@Override
236-
public ScheduledExecutorService getExecutor() {
237-
int numCpus = Runtime.getRuntime().availableProcessors();
238-
int numThreads = Math.max(DEFAULT_MIN_THREAD_COUNT, numCpus);
239-
ScheduledExecutorService executor =
240-
new ScheduledThreadPoolExecutor(numThreads, threadFactory);
241-
synchronized (this) {
242-
executors.add(executor);
243-
}
244-
return executor;
245-
}
246-
247-
/** Shuts down all executors that have been created by this {@link ExecutorProvider}. */
248-
private synchronized void shutdown() {
249-
for (ScheduledExecutorService executor : executors) {
250-
executor.shutdown();
251-
}
252-
}
253-
254-
private void awaitTermination() throws InterruptedException {
255-
for (ScheduledExecutorService executor : executors) {
256-
executor.awaitTermination(10L, TimeUnit.SECONDS);
257-
}
258-
}
259-
}
260-
261210
private static final PathTemplate PROJECT_NAME_TEMPLATE =
262211
PathTemplate.create("projects/{project}");
263212
private static final PathTemplate OPERATION_NAME_TEMPLATE =
@@ -277,7 +226,6 @@ private void awaitTermination() throws InterruptedException {
277226
CLIENT_LIBRARY_LANGUAGE + "/" + GaxProperties.getLibraryVersion(GapicSpannerRpc.class);
278227
private static final String API_FILE = "grpc-gcp-apiconfig.json";
279228

280-
private final ManagedInstantiatingExecutorProvider executorProvider;
281229
private boolean rpcIsClosed;
282230
private final SpannerStub spannerStub;
283231
private final SpannerStub partitionedDmlStub;
@@ -356,13 +304,6 @@ public GapicSpannerRpc(final SpannerOptions options) {
356304
this.compressorName = options.getCompressorName();
357305

358306
if (initializeStubs) {
359-
// Create a managed executor provider.
360-
this.executorProvider =
361-
new ManagedInstantiatingExecutorProvider(
362-
new ThreadFactoryBuilder()
363-
.setDaemon(true)
364-
.setNameFormat(options.getTransportChannelExecutorThreadNameFormat())
365-
.build());
366307
// First check if SpannerOptions provides a TransportChannelProvider. Create one
367308
// with information gathered from SpannerOptions if none is provided
368309
InstantiatingGrpcChannelProvider.Builder defaultChannelProviderBuilder =
@@ -373,11 +314,6 @@ public GapicSpannerRpc(final SpannerOptions options) {
373314
.setMaxInboundMetadataSize(MAX_METADATA_SIZE)
374315
.setPoolSize(options.getNumChannels())
375316

376-
// Before updating this method to setExecutor, please verify with a code owner on
377-
// the lowest version of gax-grpc that needs to be supported. Currently v1.47.17,
378-
// which doesn't support the setExecutor variant.
379-
.setExecutorProvider(executorProvider)
380-
381317
// Set a keepalive time of 120 seconds to help long running
382318
// commit GRPC calls succeed
383319
.setKeepAliveTime(Duration.ofSeconds(GRPC_KEEPALIVE_SECONDS))
@@ -536,7 +472,6 @@ public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCalla
536472
this.databaseAdminStubSettings = null;
537473
this.spannerWatchdog = null;
538474
this.partitionedDmlRetrySettings = null;
539-
this.executorProvider = null;
540475
}
541476
}
542477

@@ -1932,15 +1867,13 @@ public void shutdown() {
19321867
this.instanceAdminStub.close();
19331868
this.databaseAdminStub.close();
19341869
this.spannerWatchdog.shutdown();
1935-
this.executorProvider.shutdown();
19361870

19371871
try {
19381872
this.spannerStub.awaitTermination(10L, TimeUnit.SECONDS);
19391873
this.partitionedDmlStub.awaitTermination(10L, TimeUnit.SECONDS);
19401874
this.instanceAdminStub.awaitTermination(10L, TimeUnit.SECONDS);
19411875
this.databaseAdminStub.awaitTermination(10L, TimeUnit.SECONDS);
19421876
this.spannerWatchdog.awaitTermination(10L, TimeUnit.SECONDS);
1943-
this.executorProvider.awaitTermination();
19441877
} catch (InterruptedException e) {
19451878
throw SpannerExceptionFactory.propagateInterrupt(e);
19461879
}
@@ -1954,7 +1887,6 @@ public void shutdownNow() {
19541887
this.instanceAdminStub.close();
19551888
this.databaseAdminStub.close();
19561889
this.spannerWatchdog.shutdown();
1957-
this.executorProvider.shutdown();
19581890

19591891
this.spannerStub.shutdownNow();
19601892
this.partitionedDmlStub.shutdownNow();

google-cloud-spanner/src/test/java/com/google/cloud/spanner/BaseSessionPoolTest.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ public ScheduledExecutorService get() {
5454

5555
@Override
5656
public void release(ScheduledExecutorService executor) {
57-
executor.shutdown();
57+
try {
58+
executor.shutdown();
59+
} catch (Throwable ignore) {
60+
}
5861
}
5962
}
6063

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -923,14 +923,22 @@ public void testCustomAsyncExecutorProvider() {
923923
@Test
924924
public void testDefaultNumChannelsWithGrpcGcpExtensionEnabled() {
925925
SpannerOptions options =
926-
SpannerOptions.newBuilder().setProjectId("test-project").enableGrpcGcpExtension().build();
926+
SpannerOptions.newBuilder()
927+
.setProjectId("test-project")
928+
.setCredentials(NoCredentials.getInstance())
929+
.enableGrpcGcpExtension()
930+
.build();
927931

928932
assertEquals(SpannerOptions.GRPC_GCP_ENABLED_DEFAULT_CHANNELS, options.getNumChannels());
929933
}
930934

931935
@Test
932936
public void testDefaultNumChannelsWithGrpcGcpExtensionDisabled() {
933-
SpannerOptions options = SpannerOptions.newBuilder().setProjectId("test-project").build();
937+
SpannerOptions options =
938+
SpannerOptions.newBuilder()
939+
.setProjectId("test-project")
940+
.setCredentials(NoCredentials.getInstance())
941+
.build();
934942

935943
assertEquals(SpannerOptions.DEFAULT_CHANNELS, options.getNumChannels());
936944
}
@@ -943,6 +951,7 @@ public void testNumChannelsWithGrpcGcpExtensionEnabled() {
943951
SpannerOptions options1 =
944952
SpannerOptions.newBuilder()
945953
.setProjectId("test-project")
954+
.setCredentials(NoCredentials.getInstance())
946955
.setNumChannels(numChannels)
947956
.enableGrpcGcpExtension()
948957
.build();
@@ -954,6 +963,7 @@ public void testNumChannelsWithGrpcGcpExtensionEnabled() {
954963
SpannerOptions options2 =
955964
SpannerOptions.newBuilder()
956965
.setProjectId("test-project")
966+
.setCredentials(NoCredentials.getInstance())
957967
.enableGrpcGcpExtension()
958968
.setNumChannels(numChannels)
959969
.build();
@@ -972,12 +982,19 @@ public void checkCreatedInstanceWhenGrpcGcpExtensionDisabled() {
972982
Spanner spanner2 = options1.getService();
973983

974984
assertNotSame(spanner1, spanner2);
985+
986+
spanner1.close();
987+
spanner2.close();
975988
}
976989

977990
@Test
978991
public void checkCreatedInstanceWhenGrpcGcpExtensionEnabled() {
979992
SpannerOptions options =
980-
SpannerOptions.newBuilder().setProjectId("test-project").enableGrpcGcpExtension().build();
993+
SpannerOptions.newBuilder()
994+
.setProjectId("test-project")
995+
.setCredentials(NoCredentials.getInstance())
996+
.enableGrpcGcpExtension()
997+
.build();
981998
SpannerOptions options1 = options.toBuilder().build();
982999
assertEquals(true, options.isGrpcGcpExtensionEnabled());
9831000
assertEquals(options.isGrpcGcpExtensionEnabled(), options1.isGrpcGcpExtensionEnabled());
@@ -986,5 +1003,8 @@ public void checkCreatedInstanceWhenGrpcGcpExtensionEnabled() {
9861003
Spanner spanner2 = options1.getService();
9871004

9881005
assertNotSame(spanner1, spanner2);
1006+
1007+
spanner1.close();
1008+
spanner2.close();
9891009
}
9901010
}

0 commit comments

Comments
 (0)