Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connection pool size with postgres r2dbc-pool

I'm not able to open more than 10 connections with spring-webflux and r2dbc (with r2dbc-pool driver 0.8.0.M8). My config looks like:

@Configuration
public class PostgresConfig extends AbstractR2dbcConfiguration {

  @Override
  @Bean
  public ConnectionFactory connectionFactory() {
    ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
        .option(DRIVER, "pool")
        .option(PROTOCOL, "postgresql")
        .option(HOST, host)
        .option(USER, user)
        .option(PASSWORD, password)
        .option(DATABASE, database)
        .build());
    ConnectionPoolConfiguration configuration = ConnectionPoolConfiguration.builder(connectionFactory)
        .maxIdleTime(Duration.ofMinutes(30))
        .initialSize(initialSize)
        .maxSize(maxSize)
        .maxCreateConnectionTime(Duration.ofSeconds(1))
        .build();
    return new ConnectionPool(configuration);
  }
}

When I'm specifying more than 10 connections I get errors like:

org.springframework.dao.DataAccessResourceFailureException: 
Failed to obtain R2DBC Connection; nested exception is 
java.util.concurrent.TimeoutException: 
Did not observe any item or terminal signal within 1000ms in 'lift' 
(and no fallback has been configured)
    at org.springframework.data.r2dbc.connectionfactory.ConnectionFactoryUtils
    .lambda$getConnection$0(ConnectionFactoryUtils.java:71)

Moreover, number of connections remain the same as initial size. New connections are not created.

like image 666
Nikita Avatar asked Dec 14 '22 10:12

Nikita


2 Answers

Spring boot (at least 2.3.4) have a tricky "gotcha" regarding the pool size when set by properties/yaml. If you include "pool" in your database url, then the size set (initial size or max size) won't have any effect and the defaults for the r2dbc pool will be used, 10 and 10.

This is due to PooledConnectionFactoryCondition in ConnectionFactoryConfigurations.java failing when both spring.r2dbc.pool.enabled=true, which it is if the r2dbc-pool dependency is on the classpath, and "pool" being part of the spring.r2dbc.url property.

From the PooledConnectionFactoryCondition docs:

Condition that checks that a ConnectionPool is requested. The condition matches if pooling was opt-in via configuration and the r2dbc url does not contain pooling-related options.

This in turn does lead to the ConnectionPool bean not being created.

Skip the "pool" keyword in the r2dbc url property and have the r2dbc-pool dependency, then you will get a correctly configured pool.

like image 189
MrGrandeluxe Avatar answered Dec 30 '22 23:12

MrGrandeluxe


Ok, the MAX_SIZE should be also specified for ConnectionFactoryOptions. Otherwise connection pool size still remains 10.

import static io.r2dbc.pool.PoolingConnectionFactoryProvider.MAX_SIZE;

    ConnectionFactory connectionFactory = ConnectionFactories.get(ConnectionFactoryOptions.builder()
        .option(DRIVER, "pool")
        .option(PROTOCOL, "postgresql")
        .option(HOST, host)
        .option(USER, user)
        .option(PASSWORD, password)
        .option(DATABASE, database)
        .option(MAX_SIZE, maxSize)
        .build());
like image 35
Nikita Avatar answered Dec 31 '22 01:12

Nikita