Skip to content

Commit

Permalink
Reactive DS idle-timeout for pooled connections
Browse files Browse the repository at this point in the history
Before Vert.x 3.9.6, the reactive SQL client pool implementation did not support idle-timeout.

So we temporarily used the TCP connection idle-timeout config to achieve the same effect (with the caveat that the connection could be closed as idle after it was borrowed but not yet used for request execution).

With quarkusio#16100, Quarkus uses Vert.x 3.9.6 so we can now apply the idle-timeout config at the pool level and get rid of the warnings in the doc.

(cherry picked from commit 9310adc)
  • Loading branch information
tsegismont authored and gsmet committed Apr 10, 2021
1 parent 256260a commit 30b7985
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 38 deletions.
25 changes: 3 additions & 22 deletions docs/src/main/asciidoc/reactive-sql-clients.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -616,9 +616,10 @@ In `application.properties` add:
quarkus.datasource.reactive.url=mysql:///quarkus_test?host=/var/run/mysqld/mysqld.sock
----

== TCP Connection `idle-timeout`
== Pooled Connection `idle-timeout`

Reactive datasources can be configured with an `idle-timeout` (in milliseconds) that applies at the TCP connection level.
Reactive datasources can be configured with an `idle-timeout` (in milliseconds).
It is the maximum time a connection remains unused in the pool before it is closed.

NOTE: The `idle-timeout` is disabled by default.

Expand All @@ -629,26 +630,6 @@ For example, you could expire idle connections after 60 minutes:
quarkus.datasource.reactive.idle-timeout=PT60M
----

[WARNING]
====
This timeout does not apply to the pool, but to the TCP connection.
If it expires while the connection is idle in the pool, the connection is closed and removed from the pool.
If it expires immediately after your borrowed the connection from the pool and before you execute a query, you will get an error.
While this is unlikely to happen, you must be prepared for such eventuality:
[source,java]
----
// Run a query, retry at most 3 times if it fails
Uni<RowSet<Row>> rowSet = client.query("SELECT id, name FROM fruits ORDER BY name ASC")
.execute()
.onFailure().retry().atMost(3);
----
====

== Configuration Reference

=== Common Datasource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public class DataSourceReactiveRuntimeConfig {
public Duration reconnectInterval = Duration.ofSeconds(1L);

/**
* The maximum time without data written to or read from a connection before it is closed.
* The maximum time a connection remains unused in the pool before it is closed.
*/
@ConfigItem(defaultValueDocumentation = "no timeout")
public Optional<Duration> idleTimeout = Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ private PoolOptions toPoolOptions(DataSourceRuntimeConfig dataSourceRuntimeConfi
poolOptions.setMaxSize(dataSourceReactiveRuntimeConfig.maxSize.getAsInt());
}

if (dataSourceReactiveRuntimeConfig.idleTimeout.isPresent()) {
int idleTimeout = Math.toIntExact(dataSourceReactiveRuntimeConfig.idleTimeout.get().toMillis());
poolOptions.setIdleTimeout(idleTimeout).setIdleTimeoutUnit(TimeUnit.MILLISECONDS);
}

return poolOptions;
}

Expand Down Expand Up @@ -144,11 +149,6 @@ private DB2ConnectOptions toConnectOptions(DataSourceRuntimeConfig dataSourceRun

connectOptions.setReconnectInterval(dataSourceReactiveRuntimeConfig.reconnectInterval.toMillis());

if (dataSourceReactiveRuntimeConfig.idleTimeout.isPresent()) {
int idleTimeout = Math.toIntExact(dataSourceReactiveRuntimeConfig.idleTimeout.get().toMillis());
connectOptions.setIdleTimeout(idleTimeout).setIdleTimeoutUnit(TimeUnit.MILLISECONDS);
}

return connectOptions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ private PoolOptions toPoolOptions(DataSourceRuntimeConfig dataSourceRuntimeConfi
poolOptions.setMaxSize(dataSourceReactiveRuntimeConfig.maxSize.getAsInt());
}

if (dataSourceReactiveRuntimeConfig.idleTimeout.isPresent()) {
int idleTimeout = Math.toIntExact(dataSourceReactiveRuntimeConfig.idleTimeout.get().toMillis());
poolOptions.setIdleTimeout(idleTimeout).setIdleTimeoutUnit(TimeUnit.MILLISECONDS);
}

return poolOptions;
}

Expand Down Expand Up @@ -153,11 +158,6 @@ private MySQLConnectOptions toMySQLConnectOptions(DataSourceRuntimeConfig dataSo

mysqlConnectOptions.setReconnectInterval(dataSourceReactiveRuntimeConfig.reconnectInterval.toMillis());

if (dataSourceReactiveRuntimeConfig.idleTimeout.isPresent()) {
int idleTimeout = Math.toIntExact(dataSourceReactiveRuntimeConfig.idleTimeout.get().toMillis());
mysqlConnectOptions.setIdleTimeout(idleTimeout).setIdleTimeoutUnit(TimeUnit.MILLISECONDS);
}

return mysqlConnectOptions;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ private PoolOptions toPoolOptions(DataSourceRuntimeConfig dataSourceRuntimeConfi
poolOptions.setMaxSize(dataSourceReactiveRuntimeConfig.maxSize.getAsInt());
}

if (dataSourceReactiveRuntimeConfig.idleTimeout.isPresent()) {
int idleTimeout = Math.toIntExact(dataSourceReactiveRuntimeConfig.idleTimeout.get().toMillis());
poolOptions.setIdleTimeout(idleTimeout).setIdleTimeoutUnit(TimeUnit.MILLISECONDS);
}

return poolOptions;
}

Expand Down Expand Up @@ -151,11 +156,6 @@ private PgConnectOptions toPgConnectOptions(DataSourceRuntimeConfig dataSourceRu

pgConnectOptions.setReconnectInterval(dataSourceReactiveRuntimeConfig.reconnectInterval.toMillis());

if (dataSourceReactiveRuntimeConfig.idleTimeout.isPresent()) {
int idleTimeout = Math.toIntExact(dataSourceReactiveRuntimeConfig.idleTimeout.get().toMillis());
pgConnectOptions.setIdleTimeout(idleTimeout).setIdleTimeoutUnit(TimeUnit.MILLISECONDS);
}

return pgConnectOptions;
}
}

0 comments on commit 30b7985

Please sign in to comment.