diff --git a/src/main/java/oracle/r2dbc/OracleR2dbcOptions.java b/src/main/java/oracle/r2dbc/OracleR2dbcOptions.java index 682bf08..a6363c5 100644 --- a/src/main/java/oracle/r2dbc/OracleR2dbcOptions.java +++ b/src/main/java/oracle/r2dbc/OracleR2dbcOptions.java @@ -56,9 +56,11 @@ private OracleR2dbcOptions() {} * ... * .build(); * - * If this option is not configured, then Oracle R2DBC will use - * {@code ForkJoinPool}'s - * {@linkplain ForkJoinPool#commonPool() common pool} by default. + * If this option is not configured, then Oracle R2DBC will + * use the {@linkplain ForkJoinPool#commonPool() common ForkJoinPool} by + * default. However, if the common {@code ForkJoinPool} has a maximum pool + * size that is potentially zero, then a single-threaded {@code Executor} will + * be used by default. */ public static final Option EXECUTOR; diff --git a/src/main/java/oracle/r2dbc/impl/OracleConnectionFactoryImpl.java b/src/main/java/oracle/r2dbc/impl/OracleConnectionFactoryImpl.java index 9019153..08b2a5a 100755 --- a/src/main/java/oracle/r2dbc/impl/OracleConnectionFactoryImpl.java +++ b/src/main/java/oracle/r2dbc/impl/OracleConnectionFactoryImpl.java @@ -102,6 +102,20 @@ */ final class OracleConnectionFactoryImpl implements ConnectionFactory { + /** + *

+ * The default executor when {@link OracleR2dbcOptions#EXECUTOR} is not + * configured. It will use the common {@code ForkJoinPool}, unless it has + * a maximum pool size of 0. See: + * https://github.com/oracle/oracle-r2dbc/issues/129 + *

+ */ + private static final Executor DEFAULT_EXECUTOR = + "0".equals(System.getProperty( + "java.util.concurrent.ForkJoinPool.common.parallelism")) + ? new ForkJoinPool(1) + : ForkJoinPool.commonPool(); + /** JDBC data source that this factory uses to open connections */ private final DataSource dataSource; @@ -200,7 +214,7 @@ final class OracleConnectionFactoryImpl implements ConnectionFactory { Object executor = options.getValue(OracleR2dbcOptions.EXECUTOR); if (executor == null) { - this.executor = ForkJoinPool.commonPool(); + this.executor = DEFAULT_EXECUTOR; } else if (executor instanceof Executor) { this.executor = (Executor) executor; @@ -267,4 +281,5 @@ public Publisher create() { public ConnectionFactoryMetadata getMetadata() { return () -> "Oracle Database"; } + } diff --git a/src/test/java/oracle/r2dbc/impl/OracleStatementImplTest.java b/src/test/java/oracle/r2dbc/impl/OracleStatementImplTest.java index eac9a04..59045cf 100644 --- a/src/test/java/oracle/r2dbc/impl/OracleStatementImplTest.java +++ b/src/test/java/oracle/r2dbc/impl/OracleStatementImplTest.java @@ -3222,7 +3222,7 @@ private void verifyConcurrentFetch(Connection connection) { // Create many statements and execute them in parallel. @SuppressWarnings({"unchecked","rawtypes"}) Publisher[] publishers = - new Publisher[Runtime.getRuntime().availableProcessors() * 4]; + new Publisher[Runtime.getRuntime().availableProcessors() * 2]; for (int i = 0; i < publishers.length; i++) {