Skip to content

Commit

Permalink
feat: support setting core pool size for async API in system property
Browse files Browse the repository at this point in the history
Add support for setting the core pool size for the thread pool that is
used for the Async API using a system property. This allows users to
change this property without having to change code, and to set the
property if they are using a framework that builds on top of the client
library, but that does not have a configuration option for setting a
custom executor provider.

Fixes #2631
  • Loading branch information
olavloite committed Sep 18, 2023
1 parent 5ebf067 commit a39d9b3
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,30 @@ public static FixedCloseableExecutorProvider create(ScheduledExecutorService exe
*/
@VisibleForTesting
static CloseableExecutorProvider createDefaultAsyncExecutorProvider() {
return createAsyncExecutorProvider(8, 60L, TimeUnit.SECONDS);
return createAsyncExecutorProvider(
getDefaultAsyncExecutorProviderCoreThreadCount(), 60L, TimeUnit.SECONDS);
}

@VisibleForTesting
static int getDefaultAsyncExecutorProviderCoreThreadCount() {
String propertyName = "SPANNER_ASYNC_NUM_CORE_THREADS";
String propertyValue = System.getProperty(propertyName, "8");
try {
int corePoolSize = Integer.parseInt(propertyValue);
if (corePoolSize < 0) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
String.format(
"The value for %s must be >=0. Invalid value: %s", propertyName, propertyValue));
}
return corePoolSize;
} catch (NumberFormatException exception) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
String.format(
"The %s system property must be a valid integer. The value %s could not be parsed as an integer.",
propertyName, propertyValue));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.Nonnull;
import org.junit.Test;
Expand Down Expand Up @@ -913,6 +914,49 @@ public void testCustomAsyncExecutorProvider() {
assertSame(service, options.getAsyncExecutorProvider().getExecutor());
}

@Test
public void testAsyncExecutorProviderCoreThreadCount() throws Exception {
assertEquals(8, SpannerOptions.getDefaultAsyncExecutorProviderCoreThreadCount());
String propertyName = "SPANNER_ASYNC_NUM_CORE_THREADS";
assertEquals(
Integer.valueOf(16),
runWithSystemProperty(
propertyName, "16", SpannerOptions::getDefaultAsyncExecutorProviderCoreThreadCount));
assertEquals(
Integer.valueOf(1),
runWithSystemProperty(
propertyName, "1", SpannerOptions::getDefaultAsyncExecutorProviderCoreThreadCount));
assertThrows(
SpannerException.class,
() ->
runWithSystemProperty(
propertyName,
"foo",
SpannerOptions::getDefaultAsyncExecutorProviderCoreThreadCount));
assertThrows(
SpannerException.class,
() ->
runWithSystemProperty(
propertyName,
"-1",
SpannerOptions::getDefaultAsyncExecutorProviderCoreThreadCount));
}

static <V> V runWithSystemProperty(
String propertyName, String propertyValue, Callable<V> callable) throws Exception {
String currentValue = System.getProperty(propertyName);
System.setProperty(propertyName, propertyValue);
try {
return callable.call();
} finally {
if (currentValue == null) {
System.clearProperty(propertyName);
} else {
System.setProperty(propertyName, currentValue);
}
}
}

@Test
public void testDefaultNumChannelsWithGrpcGcpExtensionEnabled() {
SpannerOptions options =
Expand Down

0 comments on commit a39d9b3

Please sign in to comment.