Fixes #770 by adding a new property initializationFailTimeout and deprecating

initializationFailFast.
pull/772/head
Brett Wooldridge 8 years ago
parent e3b79ee044
commit 7bab1a8ccd

@ -455,7 +455,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
} }
catch (Exception e) { catch (Exception e) {
if (poolState == POOL_NORMAL) { if (poolState == POOL_NORMAL) {
LOGGER.debug("{} - Cannot acquire connection from data source", poolName, e); LOGGER.debug("{} - Cannot acquire connection from data source", poolName, (e instanceof ConnectionSetupException ? e.getCause() : e));
} }
return null; return null;
} }
@ -508,26 +508,24 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
*/ */
private void checkFailFast() private void checkFailFast()
{ {
if (config.getInitializationFailTimeout() == 0) {
return;
}
final long startTime = clockSource.currentTime(); final long startTime = clockSource.currentTime();
boolean acquired = false;
Throwable throwable = new SQLTimeoutException("HikariCP was unable to initialize connections in pool " + poolName); Throwable throwable = new SQLTimeoutException("HikariCP was unable to initialize connections in pool " + poolName);
do { do {
try (Connection connection = newConnection()) { try (Connection connection = newConnection()) {
acquired = true;
if (!connection.getAutoCommit()) { if (!connection.getAutoCommit()) {
connection.commit(); connection.commit();
} }
return; return;
} }
catch (ConnectionSetupException e) {
throwable = e.getCause();
break;
}
catch (Throwable t) { catch (Throwable t) {
throwable = t; throwable = t;
quietlySleep(1000L); quietlySleep(1000L);
} }
} while (!acquired && clockSource.elapsedMillis(startTime) < config.getInitializationFailTimeout()); } while (clockSource.elapsedMillis(startTime) < config.getInitializationFailTimeout());
throw new PoolInitializationException(throwable); throw new PoolInitializationException(throwable);
} }

@ -348,14 +348,19 @@ abstract class PoolBase
return connection; return connection;
} }
catch (Exception e) { catch (Exception e) {
Exception cause = e;
if (e instanceof ConnectionSetupException) {
cause = (Exception) e.getCause();
}
if (connection != null) { if (connection != null) {
quietlyCloseConnection(connection, "(Failed to create/setup connection)"); quietlyCloseConnection(connection, "(Failed to create/setup connection)");
} }
else if (getLastConnectionFailure() == null) { else if (getLastConnectionFailure() == null) {
LOGGER.debug("{} - Failed to create/setup connection: {}", poolName, e.getMessage()); LOGGER.debug("{} - Failed to create/setup connection: {}", poolName, cause.getMessage());
} }
lastConnectionFailure.set(e); lastConnectionFailure.set(cause);
throw e; throw e;
} }
} }
@ -366,31 +371,36 @@ abstract class PoolBase
* @param connection a Connection * @param connection a Connection
* @throws SQLException thrown from driver * @throws SQLException thrown from driver
*/ */
private void setupConnection(final Connection connection) throws SQLException private void setupConnection(final Connection connection) throws ConnectionSetupException
{ {
if (networkTimeout == UNINITIALIZED) { try {
networkTimeout = getAndSetNetworkTimeout(connection, validationTimeout); if (networkTimeout == UNINITIALIZED) {
} networkTimeout = getAndSetNetworkTimeout(connection, validationTimeout);
else { }
setNetworkTimeout(connection, validationTimeout); else {
} setNetworkTimeout(connection, validationTimeout);
}
connection.setReadOnly(isReadOnly); connection.setReadOnly(isReadOnly);
connection.setAutoCommit(isAutoCommit); connection.setAutoCommit(isAutoCommit);
checkDriverSupport(connection); checkDriverSupport(connection);
if (transactionIsolation != defaultTransactionIsolation) { if (transactionIsolation != defaultTransactionIsolation) {
connection.setTransactionIsolation(transactionIsolation); connection.setTransactionIsolation(transactionIsolation);
} }
if (catalog != null) { if (catalog != null) {
connection.setCatalog(catalog); connection.setCatalog(catalog);
} }
executeSql(connection, config.getConnectionInitSql(), true); executeSql(connection, config.getConnectionInitSql(), true);
setNetworkTimeout(connection, networkTimeout); setNetworkTimeout(connection, networkTimeout);
}
catch (SQLException e) {
throw new ConnectionSetupException(e);
}
} }
/** /**
@ -590,6 +600,16 @@ abstract class PoolBase
// Private Static Classes // Private Static Classes
// *********************************************************************** // ***********************************************************************
static class ConnectionSetupException extends Exception
{
private static final long serialVersionUID = 929872118275916521L;
public ConnectionSetupException(Throwable t)
{
super(t);
}
}
/** /**
* Special executor used only to work around a MySQL issue that has not been addressed. * Special executor used only to work around a MySQL issue that has not been addressed.
* MySQL issue: http://bugs.mysql.com/bug.php?id=75615 * MySQL issue: http://bugs.mysql.com/bug.php?id=75615

@ -44,7 +44,7 @@ public class ConnectionRaceConditionTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(0); config.setMinimumIdle(0);
config.setMaximumPoolSize(10); config.setMaximumPoolSize(10);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setConnectionTimeout(2500); config.setConnectionTimeout(2500);
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -53,7 +53,7 @@ public class HouseKeeperCleanupTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(0); config.setMinimumIdle(0);
config.setMaximumPoolSize(10); config.setMaximumPoolSize(10);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setConnectionTimeout(2500); config.setConnectionTimeout(2500);
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setScheduledExecutorService(executor); config.setScheduledExecutorService(executor);

@ -33,7 +33,7 @@ public class RampUpDown
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(5); config.setMinimumIdle(5);
config.setMaximumPoolSize(60); config.setMaximumPoolSize(60);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -64,7 +64,7 @@ public class ShutdownTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(0); config.setMinimumIdle(0);
config.setMaximumPoolSize(10); config.setMaximumPoolSize(10);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -115,7 +115,7 @@ public class ShutdownTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(10); config.setMinimumIdle(10);
config.setMaximumPoolSize(10); config.setMaximumPoolSize(10);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -145,7 +145,7 @@ public class ShutdownTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(5); config.setMinimumIdle(5);
config.setMaximumPoolSize(5); config.setMaximumPoolSize(5);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -172,7 +172,7 @@ public class ShutdownTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(10); config.setMinimumIdle(10);
config.setMaximumPoolSize(10); config.setMaximumPoolSize(10);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -198,7 +198,7 @@ public class ShutdownTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(5); config.setMinimumIdle(5);
config.setMaximumPoolSize(5); config.setMaximumPoolSize(5);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -226,7 +226,7 @@ public class ShutdownTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(0); config.setMinimumIdle(0);
config.setMaximumPoolSize(5); config.setMaximumPoolSize(5);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -249,7 +249,7 @@ public class ShutdownTest
config.setMaximumPoolSize(5); config.setMaximumPoolSize(5);
config.setConnectionTimeout(1000); config.setConnectionTimeout(1000);
config.setValidationTimeout(1000); config.setValidationTimeout(1000);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -267,7 +267,7 @@ public class ShutdownTest
config.setMaximumPoolSize(5); config.setMaximumPoolSize(5);
config.setConnectionTimeout(1000); config.setConnectionTimeout(1000);
config.setValidationTimeout(1000); config.setValidationTimeout(1000);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -46,7 +46,7 @@ public class TestConcurrentBag
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(2); config.setMaximumPoolSize(2);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -74,7 +74,7 @@ public class TestConnectionTimeoutRetry
config.setMaximumPoolSize(1); config.setMaximumPoolSize(1);
config.setConnectionTimeout(2800); config.setConnectionTimeout(2800);
config.setValidationTimeout(2800); config.setValidationTimeout(2800);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -114,7 +114,7 @@ public class TestConnections
config.setMaximumPoolSize(1); config.setMaximumPoolSize(1);
config.setConnectionTimeout(2500); config.setConnectionTimeout(2500);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
System.setProperty("com.zaxxer.hikari.housekeeping.periodMs", "100"); System.setProperty("com.zaxxer.hikari.housekeeping.periodMs", "100");
@ -268,7 +268,7 @@ public class TestConnections
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(4); config.setMaximumPoolSize(4);
config.setConnectionTimeout(1000); config.setConnectionTimeout(1000);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -328,7 +328,7 @@ public class TestConnections
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(4); config.setMaximumPoolSize(4);
config.setConnectionTimeout(20000); config.setConnectionTimeout(20000);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -503,14 +503,19 @@ public class TestConnections
config.setInitializationFailTimeout(TimeUnit.SECONDS.toMillis(2)); config.setInitializationFailTimeout(TimeUnit.SECONDS.toMillis(2));
config.setDataSource(stubDataSource); config.setDataSource(stubDataSource);
try (HikariDataSource ds = new HikariDataSource(config); Connection c = ds.getConnection()) { try (HikariDataSource ds = new HikariDataSource(config)) {
Assert.fail("getConnection() should have failed"); try (Connection c = ds.getConnection()) {
Assert.fail("getConnection() should have failed");
}
catch (SQLException e) {
Assert.assertSame("Bad query or something.", e.getNextException().getMessage());
}
} }
catch (SQLException e) { catch (PoolInitializationException e) {
Assert.assertSame("Bad query or something.", e.getNextException().getMessage()); Assert.assertSame("Bad query or something.", e.getCause().getMessage());
} }
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
try (HikariDataSource ds = new HikariDataSource(config)) { try (HikariDataSource ds = new HikariDataSource(config)) {
Assert.fail("Initialization should have failed"); Assert.fail("Initialization should have failed");
} }

@ -56,7 +56,7 @@ public class TestMetrics
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(1); config.setMaximumPoolSize(1);
config.setMetricRegistry(metricRegistry); config.setMetricRegistry(metricRegistry);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setPoolName("test"); config.setPoolName("test");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -87,7 +87,7 @@ public class TestMetrics
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(1); config.setMaximumPoolSize(1);
config.setMetricRegistry(metricRegistry); config.setMetricRegistry(metricRegistry);
config.setInitializationFailFast(false); config.setInitializationFailTimeout(Long.MAX_VALUE);
config.setPoolName("test"); config.setPoolName("test");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -38,7 +38,7 @@ public class UnwrapTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(1); config.setMaximumPoolSize(1);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
@ -60,7 +60,7 @@ public class UnwrapTest
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
config.setMinimumIdle(1); config.setMinimumIdle(1);
config.setMaximumPoolSize(1); config.setMaximumPoolSize(1);
config.setInitializationFailFast(true); config.setInitializationFailTimeout(0);
config.setConnectionTestQuery("VALUES 1"); config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

Loading…
Cancel
Save