Add validationTimeout.

pull/253/head
Brett Wooldridge 10 years ago
parent f498dfa608
commit b544c21cf3

@ -39,6 +39,7 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class);
private static final long CONNECTION_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
private static final long VALIDATION_TIMEOUT = TimeUnit.SECONDS.toMillis(5);
private static final long IDLE_TIMEOUT = TimeUnit.MINUTES.toMillis(10);
private static final long MAX_LIFETIME = TimeUnit.MINUTES.toMillis(30);
@ -48,6 +49,7 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
// Properties changeable at runtime through the MBean
//
private volatile long connectionTimeout;
private volatile long validationTimeout;
private volatile long idleTimeout;
private volatile long leakDetectionThreshold;
private volatile long maxLifetime;
@ -88,6 +90,7 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
dataSourceProperties = new Properties();
connectionTimeout = CONNECTION_TIMEOUT;
validationTimeout = VALIDATION_TIMEOUT;
idleTimeout = IDLE_TIMEOUT;
isAutoCommit = true;
isInitializationFailFast = true;
@ -263,14 +266,33 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
if (connectionTimeoutMs == 0) {
this.connectionTimeout = Integer.MAX_VALUE;
}
else if (connectionTimeoutMs < 100) {
throw new IllegalArgumentException("connectionTimeout cannot be less than 100ms");
else if (connectionTimeoutMs < 1000) {
throw new IllegalArgumentException("connectionTimeout cannot be less than 1000ms");
}
else {
this.connectionTimeout = connectionTimeoutMs;
}
}
/** {@inheritDoc} */
@Override
public long getValidationTimeout()
{
return validationTimeout;
}
/** {@inheritDoc} */
@Override
public void setValidationTimeout(long validationTimeoutMs)
{
if (validationTimeoutMs < 1000) {
throw new IllegalArgumentException("connectionTimeout cannot be less than 1000ms");
}
else {
this.validationTimeout = validationTimeoutMs;
}
}
/**
* Get the {@link DataSource} that has been explicitly specified to be wrapped by the
* pool.
@ -708,6 +730,11 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
logger.warn("No connection wait timeout is set, this might cause an infinite wait.");
}
if (validationTimeout > connectionTimeout) {
logger.warn("validationTimeout is greater than connectionTimeout, setting validationTimeout to connectionTimeout.");
validationTimeout = connectionTimeout;
}
if (minIdle < 0 || minIdle > maxPoolSize) {
minIdle = maxPoolSize;
}

@ -41,6 +41,22 @@ public interface HikariConfigMBean
*/
void setConnectionTimeout(long connectionTimeoutMs);
/**
* Get the maximum number of milliseconds that the pool will wait for a connection to be validated as
* alive.
*
* @return the validation timeout in milliseconds
*/
long getValidationTimeout();
/**
* Sets the maximum number of milliseconds that the pool will wait for a connection to be validated as
* alive.
*
* @param validationTimeoutMs the validation timeout in milliseconds
*/
void setValidationTimeout(long validationTimeoutMs);
/**
* This property controls the maximum amount of time (in milliseconds) that a connection is allowed to sit
* idle in the pool. Whether a connection is retired as idle or not is subject to a maximum variation of +30

@ -89,6 +89,7 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
protected volatile int poolState;
protected volatile long connectionTimeout;
protected volatile long validationTimeout;
private final LeakTask leakTask;
private final DataSource dataSource;
@ -129,6 +130,7 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
this.connectionBag = createConcurrentBag(this);
this.totalConnections = new AtomicInteger();
this.connectionTimeout = configuration.getConnectionTimeout();
this.validationTimeout = configuration.getValidationTimeout();
this.lastConnectionFailure = new AtomicReference<Throwable>();
this.isReadOnly = configuration.isReadOnly();
@ -183,7 +185,7 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
}
final long now = System.currentTimeMillis();
if (bagEntry.evicted || (now - bagEntry.lastAccess > ALIVE_BYPASS_WINDOW && !isConnectionAlive(bagEntry.connection, timeout))) {
if (bagEntry.evicted || (now - bagEntry.lastAccess > ALIVE_BYPASS_WINDOW && !isConnectionAlive(bagEntry.connection))) {
closeConnection(bagEntry); // Throw away the dead connection and try again
timeout = connectionTimeout - elapsedTimeMs(start);
}
@ -378,14 +380,14 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
final boolean timeoutEnabled = (connectionTimeout != Integer.MAX_VALUE);
final long timeoutMs = timeoutEnabled ? Math.max(250L, connectionTimeout) : 0L;
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, timeoutMs, timeoutEnabled);
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, timeoutMs);
transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation);
poolUtils.setupConnection(connection, isAutoCommit, isReadOnly, transactionIsolation, catalog);
connectionCustomizer.customize(connection);
poolUtils.executeSql(connection, configuration.getConnectionInitSql(), isAutoCommit);
poolUtils.setNetworkTimeout(connection, originalTimeout, timeoutEnabled);
poolUtils.setNetworkTimeout(connection, originalTimeout);
connectionBag.add(new PoolBagEntry(connection, this));
lastConnectionFailure.set(null);
@ -431,7 +433,7 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
* @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out
*/
protected abstract boolean isConnectionAlive(final Connection connection, final long timeoutMs);
protected abstract boolean isConnectionAlive(final Connection connection);
/**
* Attempt to abort() active connections on Java7+, or close() them on Java6.

@ -49,7 +49,7 @@ public final class PoolUtilities
{
if (connection != null) {
try {
setNetworkTimeout(connection, TimeUnit.SECONDS.toMillis(30), true);
setNetworkTimeout(connection, TimeUnit.SECONDS.toMillis(30));
connection.close();
}
catch (Throwable e) {
@ -177,12 +177,11 @@ public final class PoolUtilities
*
* @param connection the connection to set the network timeout on
* @param timeoutMs the number of milliseconds before timeout
* @param isUseNetworkTimeout true if the network timeout should be set, false otherwise
* @return the pre-existing network timeout value
*/
public int getAndSetNetworkTimeout(final Connection connection, final long timeoutMs, final boolean isUseNetworkTimeout)
public int getAndSetNetworkTimeout(final Connection connection, final long timeoutMs)
{
if (isUseNetworkTimeout && isNetworkTimeoutSupported) {
if (isNetworkTimeoutSupported) {
try {
final int networkTimeout = connection.getNetworkTimeout();
connection.setNetworkTimeout(executorService, (int) timeoutMs);
@ -203,11 +202,10 @@ public final class PoolUtilities
*
* @param connection the connection to set the network timeout on
* @param timeoutMs the number of milliseconds before timeout
* @param isUseNetworkTimeout true if the network timeout should be set, false otherwise
*/
public void setNetworkTimeout(final Connection connection, final long timeoutMs, final boolean isUseNetworkTimeout)
public void setNetworkTimeout(final Connection connection, final long timeoutMs)
{
if (isUseNetworkTimeout && isNetworkTimeoutSupported) {
if (isNetworkTimeoutSupported) {
try {
connection.setNetworkTimeout(executorService, (int) timeoutMs);
}

@ -139,17 +139,16 @@ public final class HikariPool extends BaseHikariPool
* @return true if the connection is alive, false if it is not alive or we timed out
*/
@Override
protected boolean isConnectionAlive(final Connection connection, final long timeoutMs)
protected boolean isConnectionAlive(final Connection connection)
{
try {
final boolean timeoutEnabled = (connectionTimeout != Integer.MAX_VALUE);
int timeoutSec = timeoutEnabled ? (int) Math.max(1L, TimeUnit.MILLISECONDS.toSeconds(timeoutMs)) : 0;
final int timeoutSec = (int) TimeUnit.MILLISECONDS.toSeconds(validationTimeout);
if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec);
}
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, Math.max(1000, (int) timeoutMs), timeoutEnabled);
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, validationTimeout);
Statement statement = connection.createStatement();
try {
@ -164,7 +163,7 @@ public final class HikariPool extends BaseHikariPool
connection.rollback();
}
poolUtils.setNetworkTimeout(connection, originalTimeout, timeoutEnabled);
poolUtils.setNetworkTimeout(connection, originalTimeout);
return true;
}

@ -118,21 +118,19 @@ public final class HikariPool extends BaseHikariPool
* Check whether the connection is alive or not.
*
* @param connection the connection to test
* @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out
*/
@Override
protected boolean isConnectionAlive(final Connection connection, final long timeoutMs)
protected boolean isConnectionAlive(final Connection connection)
{
try {
final boolean timeoutEnabled = (connectionTimeout != Integer.MAX_VALUE);
int timeoutSec = timeoutEnabled ? (int) Math.max(1L, TimeUnit.MILLISECONDS.toSeconds(timeoutMs)) : 0;
final int timeoutSec = (int) TimeUnit.MILLISECONDS.toSeconds(validationTimeout);
if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec);
}
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, Math.max(1000, (int) timeoutMs), timeoutEnabled);
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, validationTimeout);
try (Statement statement = connection.createStatement()) {
poolUtils.setQueryTimeout(statement, timeoutSec);
@ -143,7 +141,7 @@ public final class HikariPool extends BaseHikariPool
connection.rollback();
}
poolUtils.setNetworkTimeout(connection, originalTimeout, timeoutEnabled);
poolUtils.setNetworkTimeout(connection, originalTimeout);
return true;
}
@ -206,6 +204,7 @@ public final class HikariPool extends BaseHikariPool
logPoolState("Before cleanup ");
connectionTimeout = configuration.getConnectionTimeout(); // refresh member in case it changed
validationTimeout = configuration.getValidationTimeout(); // refresh member in case it changed
final long now = System.currentTimeMillis();
final long idleTimeout = configuration.getIdleTimeout();

Loading…
Cancel
Save