clickhouse-java
clickhouse-java copied to clipboard
"R2dbcNonTransientResourceException: Connection validation failed" after connection is closed due to maxIdleTime
Hi,
I use clickhouse-r2dbc version 0.4.6 and connection pooling. After 30 minutes or inactivity (default value for maxIdleTime) connection is closed and no further queries run with existing connection factory.
This is reproduction scenario:
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryOptions;
import reactor.core.publisher.Flux;
public class ReproduceBug {
public static void select1(ConnectionFactory connectionFactory) {
Flux.usingWhen(connectionFactory.create(),
connection -> {
var statement = connection.createStatement("select 1");
return statement.execute();
}, Connection::close)
.collectList()
.block();
}
public static void main(String[] args) throws InterruptedException {
var options = ConnectionFactoryOptions.parse(
"r2dbc:pool:clickhouse:http://localhost:8123?maxIdleTime=PT1S"
);
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
select1(connectionFactory);
Thread.sleep(2000L);
select1(connectionFactory);
}
}
Causes an error:
Exception in thread "main" io.r2dbc.spi.R2dbcNonTransientResourceException: Connection validation failed
at io.r2dbc.pool.Validation.lambda$validate$2(Validation.java:45)
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:179)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545)
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.request(FluxHandleFuseable.java:260)
at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onSubscribe(MonoIgnoreElements.java:72)
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onSubscribe(FluxHandleFuseable.java:164)
at reactor.core.publisher.FluxJust.subscribe(FluxJust.java:68)
at reactor.core.publisher.Mono.subscribe(Mono.java:4495)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263)
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at io.r2dbc.pool.MonoDiscardOnCancel.subscribe(MonoDiscardOnCancel.java:50)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165)
at reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:467)
at reactor.pool.SimpleDequePool.lambda$drainLoop$8(SimpleDequePool.java:372)
at reactor.core.scheduler.ImmediateScheduler.schedule(ImmediateScheduler.java:52)
at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:372)
at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:604)
at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:298)
at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194)
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341)
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117)
at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:722)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53)
at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117)
at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50)
at reactor.core.publisher.Mono.subscribe(Mono.java:4480)
at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104)
at reactor.core.publisher.Mono.subscribe(Mono.java:4495)
at reactor.core.publisher.Mono.block(Mono.java:1711)
at ReproduceBug.select1(ReproduceBug.java:16)
at ReproduceBug.main(ReproduceBug.java:26)
Suppressed: java.lang.Exception: #block terminated with an error
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:103)
at reactor.core.publisher.Mono.block(Mono.java:1712)
... 2 more
For sure works if I removed pool from connection string. Another workaround - set maxIdleTime to indefinite.
Is that bug in clickhouse-java implementation or in r2dbc-pool?