Skip to content

Commit 7205365

Browse files
committed
Introduce enableKeepAlive() and readTimeout() in JDBC Runtime config
1 parent 51ee938 commit 7205365

8 files changed

Lines changed: 117 additions & 1 deletion

File tree

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/AgroalConnectionConfigurer.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.agroal.runtime;
22

3+
import java.time.Duration;
34
import java.util.Map;
45

56
import org.jboss.logging.Logger;
@@ -28,4 +29,14 @@ default void setExceptionSorter(String databaseKind, AgroalDataSourceConfigurati
2829
databaseKind);
2930
}
3031

32+
default void setKeepAlive(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
33+
Map<String, String> additionalJdbcProperties, boolean keepAlive) {
34+
log.warnv("Agroal does not support KeepAlive for database kind: {0}", databaseKind);
35+
}
36+
37+
default void setReadTimeout(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
38+
Map<String, String> additionalJdbcProperties, Duration timeout) {
39+
log.warnv("Agroal does not support setting the read timeout for database kind: {0}", databaseKind);
40+
}
41+
3142
}

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceJdbcRuntimeConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,16 @@ public interface DataSourceJdbcRuntimeConfig {
180180
@ConfigDocDefault("false if quarkus.datasource.jdbc.telemetry=false and true if quarkus.datasource.jdbc.telemetry=true")
181181
Optional<Boolean> telemetry();
182182

183+
/**
184+
* Enable KeepAlive for this datasource. When enabled, the datasource will attempt to keep connections alive by sending
185+
* periodic keep-alive messages to the database. Each JDBC driver has its own implementation of keep-alive, and the actual
186+
* behavior may vary depending on the driver and database being used.
187+
*/
188+
Optional<Boolean> enableKeepAlive();
189+
190+
/**
191+
* The timeout value used for socket read operations. If reading from the server takes longer than this value, the
192+
* connection is closed.
193+
*/
194+
Optional<Duration> readTimeout();
183195
}

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSources.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ public AgroalDataSource createDataSource(String dataSourceName, boolean otelEnab
198198
agroalConnectionConfigurer.disableSslSupport(resolvedDbKind, dataSourceConfiguration,
199199
dataSourceJdbcRuntimeConfig.additionalJdbcProperties());
200200
}
201+
202+
if (dataSourceJdbcRuntimeConfig.enableKeepAlive().isPresent()) {
203+
agroalConnectionConfigurer.setKeepAlive(resolvedDbKind, dataSourceConfiguration,
204+
dataSourceJdbcRuntimeConfig.additionalJdbcProperties(),
205+
dataSourceJdbcRuntimeConfig.enableKeepAlive().get());
206+
}
207+
208+
if (dataSourceJdbcRuntimeConfig.readTimeout().isPresent()) {
209+
agroalConnectionConfigurer.setReadTimeout(resolvedDbKind, dataSourceConfiguration,
210+
dataSourceJdbcRuntimeConfig.additionalJdbcProperties(), dataSourceJdbcRuntimeConfig.readTimeout().get());
211+
}
212+
201213
//we use a custom cache for two reasons:
202214
//fast thread local cache should be faster
203215
//and it prevents a thread local leak

extensions/jdbc/jdbc-mariadb/runtime/src/main/java/io/quarkus/jdbc/mariadb/runtime/MariaDBAgroalConnectionConfigurer.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.jdbc.mariadb.runtime;
22

3+
import java.time.Duration;
34
import java.util.Map;
45

56
import io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier;
@@ -23,4 +24,21 @@ public void setExceptionSorter(String databaseKind, AgroalDataSourceConfiguratio
2324
dataSourceConfiguration.connectionPoolConfiguration().exceptionSorter(new MySQLExceptionSorter());
2425
}
2526

27+
@Override
28+
public void setKeepAlive(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
29+
Map<String, String> additionalJdbcProperties, boolean keepAlive) {
30+
// MariaDB JDBC driver uses "tcpKeepAlive" property to enable keep-alive. Default is true.
31+
// See https://mariadb.com/docs/connectors/mariadb-connector-j/about-mariadb-connector-j
32+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration().jdbcProperty("tcpKeepAlive",
33+
Boolean.toString(keepAlive));
34+
}
35+
36+
@Override
37+
public void setReadTimeout(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
38+
Map<String, String> additionalJdbcProperties, Duration timeout) {
39+
// MariaDB JDBC driver uses "socketTimeout" property to configure socket timeout.
40+
// See https://mariadb.com/docs/connectors/mariadb-connector-j/about-mariadb-connector-j
41+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration().jdbcProperty("socketTimeout",
42+
Long.toString(timeout.toMillis()));
43+
}
2644
}

extensions/jdbc/jdbc-mssql/runtime/src/main/java/io/quarkus/jdbc/mssql/runtime/MsSQLAgroalConnectionConfigurer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.jdbc.mssql.runtime;
22

3+
import java.time.Duration;
34
import java.util.Map;
45

56
import io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier;
@@ -22,4 +23,13 @@ public void setExceptionSorter(String databaseKind, AgroalDataSourceConfiguratio
2223
dataSourceConfiguration.connectionPoolConfiguration().exceptionSorter(new MSSQLExceptionSorter());
2324
}
2425

26+
@Override
27+
public void setReadTimeout(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
28+
Map<String, String> additionalJdbcProperties, Duration timeout) {
29+
// MSSQL socket timeout is configured using the "socketTimeout" property, which is in milliseconds
30+
// See https://learn.microsoft.com/en-us/sql/connect/jdbc/understand-timeouts
31+
// https://learn.microsoft.com/en-us/sql/connect/jdbc/setting-the-connection-properties
32+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration()
33+
.jdbcProperty("socketTimeout", Long.toString(timeout.toMillis()));
34+
}
2535
}

extensions/jdbc/jdbc-mysql/runtime/src/main/java/io/quarkus/jdbc/mysql/runtime/MySQLAgroalConnectionConfigurer.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.jdbc.mysql.runtime;
22

3+
import java.time.Duration;
34
import java.util.Map;
45

56
import io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier;
@@ -22,4 +23,20 @@ public void setExceptionSorter(String databaseKind, AgroalDataSourceConfiguratio
2223
dataSourceConfiguration.connectionPoolConfiguration().exceptionSorter(new MySQLExceptionSorter());
2324
}
2425

26+
@Override
27+
public void setKeepAlive(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
28+
Map<String, String> additionalJdbcProperties, boolean keepAlive) {
29+
// The MySQL JDBC driver has its own keep-alive mechanism that can be enabled via a JDBC property
30+
// https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-networking.html
31+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration()
32+
.jdbcProperty("tcpKeepAlive", Boolean.toString(keepAlive));
33+
}
34+
35+
@Override
36+
public void setReadTimeout(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
37+
Map<String, String> additionalJdbcProperties, Duration timeout) {
38+
// https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-networking.html
39+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration()
40+
.jdbcProperty("socketTimeout", Long.toString(timeout.toMillis()));
41+
}
2542
}

extensions/jdbc/jdbc-oracle/runtime/src/main/java/io/quarkus/jdbc/oracle/runtime/OracleAgroalConnectionConfigurer.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.jdbc.oracle.runtime;
22

3+
import java.time.Duration;
34
import java.util.Map;
45

56
import io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier;
@@ -14,7 +15,7 @@ public class OracleAgroalConnectionConfigurer implements AgroalConnectionConfigu
1415
/**
1516
* Oracle connection properties are documented here:
1617
* https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/jdbc/OracleConnection.html#Transport_Layer_Security__TLS_SSL_
17-
*
18+
* <p>
1819
* SSL seems to be disabled by default, so rather than disabling it explicitly we check that the user didn't attempt to
1920
* enable it.
2021
*/
@@ -33,4 +34,21 @@ public void setExceptionSorter(String databaseKind, AgroalDataSourceConfiguratio
3334
dataSourceConfiguration.connectionPoolConfiguration().exceptionSorter(new OracleExceptionSorter());
3435
}
3536

37+
@Override
38+
public void setKeepAlive(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
39+
Map<String, String> additionalJdbcProperties, boolean keepAlive) {
40+
// Oracle keep-alive is configured via the "oracle.net.keepAlive" property. Defaults to false.
41+
// https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/jdbc/OracleConnection.html
42+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration()
43+
.jdbcProperty("oracle.net.keepAlive", Boolean.toString(keepAlive));
44+
}
45+
46+
@Override
47+
public void setReadTimeout(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
48+
Map<String, String> additionalJdbcProperties, Duration timeout) {
49+
// Oracle socket timeout is configured via the "oracle.jdbc.ReadTimeout" property, which is in milliseconds
50+
// https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/jdbc/OracleConnection.html
51+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration()
52+
.jdbcProperty("oracle.jdbc.ReadTimeout", Long.toString(timeout.toMillis()));
53+
}
3654
}

extensions/jdbc/jdbc-postgresql/runtime/src/main/java/io/quarkus/jdbc/postgresql/runtime/PostgreSQLAgroalConnectionConfigurer.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.jdbc.postgresql.runtime;
22

3+
import java.time.Duration;
34
import java.util.Map;
45

56
import io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier;
@@ -23,4 +24,21 @@ public void setExceptionSorter(String databaseKind, AgroalDataSourceConfiguratio
2324
dataSourceConfiguration.connectionPoolConfiguration().exceptionSorter(new PostgreSQLExceptionSorter());
2425
}
2526

27+
@Override
28+
public void setKeepAlive(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
29+
Map<String, String> additionalJdbcProperties, boolean keepAlive) {
30+
// The PostgreSQL JDBC driver has its own keep-alive mechanism that can be enabled via a JDBC property. Default is false.
31+
// See https://jdbc.postgresql.org/documentation/use/#connection-parameters
32+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration().jdbcProperty("tcpKeepAlive",
33+
Boolean.toString(keepAlive));
34+
}
35+
36+
@Override
37+
public void setReadTimeout(String databaseKind, AgroalDataSourceConfigurationSupplier dataSourceConfiguration,
38+
Map<String, String> additionalJdbcProperties, Duration timeout) {
39+
// The PostgreSQL JDBC driver uses the "socketTimeout" property to specify the socket timeout in seconds.
40+
// See https://jdbc.postgresql.org/documentation/use/#connection-parameters
41+
dataSourceConfiguration.connectionPoolConfiguration().connectionFactoryConfiguration().jdbcProperty("socketTimeout",
42+
Long.toString(timeout.getSeconds()));
43+
}
2644
}

0 commit comments

Comments
 (0)