Merge pull request #567 from nitincchauhan/dev

avoid 'more' exceptions after 'un-recoverable' exception thrown before for the connection
pull/577/head
Brett Wooldridge 9 years ago
commit 62fdb2c6c3

@ -761,6 +761,13 @@ public class HikariConfig implements HikariConfigMXBean
public void validate()
{
if (poolName == null) {
poolName = "HikariPool-" + POOL_NUMBER.getAndIncrement();
}
else if (isRegisterMbeans && poolName.contains(":")) {
throw new IllegalArgumentException("poolName cannot contain ':' when used with JMX");
}
validateNumerics();
// treat empty property as null
@ -773,33 +780,26 @@ public class HikariConfig implements HikariConfigMXBean
driverClassName = getNullIfEmpty(driverClassName);
jdbcUrl = getNullIfEmpty(jdbcUrl);
if (poolName == null) {
poolName = "HikariPool-" + POOL_NUMBER.getAndIncrement();
}
else if (isRegisterMbeans && poolName.contains(":")) {
throw new IllegalArgumentException("poolName cannot contain ':' when used with JMX");
}
// Check Data Source Options
if (dataSource != null) {
if (dataSourceClassName != null) {
LOGGER.warn("using dataSource and ignoring dataSourceClassName");
LOGGER.warn("{} - using dataSource and ignoring dataSourceClassName.", poolName);
}
}
else if (dataSourceClassName != null) {
if (driverClassName != null) {
LOGGER.error("cannot use driverClassName and dataSourceClassName together");
throw new IllegalArgumentException("cannot use driverClassName and dataSourceClassName together");
LOGGER.error("{} - cannot use driverClassName and dataSourceClassName together.", poolName);
throw new IllegalArgumentException("cannot use driverClassName and dataSourceClassName together.");
}
else if (jdbcUrl != null) {
LOGGER.warn("using dataSourceClassName and ignoring jdbcUrl");
LOGGER.warn("{} - using dataSourceClassName and ignoring jdbcUrl.", poolName);
}
}
else if (jdbcUrl != null) {
}
else if (driverClassName != null) {
LOGGER.error("jdbcUrl is required with driverClassName");
throw new IllegalArgumentException("jdbcUrl is required with driverClassName");
LOGGER.error("{} - jdbcUrl is required with driverClassName.", poolName);
throw new IllegalArgumentException("jdbcUrl is required with driverClassName.");
}
else {
LOGGER.error("{} - dataSource or dataSourceClassName or jdbcUrl is required.", poolName);
@ -814,43 +814,43 @@ public class HikariConfig implements HikariConfigMXBean
private void validateNumerics()
{
if (maxLifetime < 0) {
LOGGER.error("maxLifetime cannot be negative.");
LOGGER.error("{} - maxLifetime cannot be negative.", poolName);
throw new IllegalArgumentException("maxLifetime cannot be negative.");
}
else if (maxLifetime > 0 && maxLifetime < TimeUnit.SECONDS.toMillis(30)) {
LOGGER.warn("maxLifetime is less than 30000ms, setting to default {}ms.", MAX_LIFETIME);
LOGGER.warn("{} - maxLifetime is less than 30000ms, setting to default {}ms.", poolName, MAX_LIFETIME);
maxLifetime = MAX_LIFETIME;
}
if (idleTimeout != 0 && idleTimeout < TimeUnit.SECONDS.toMillis(10)) {
LOGGER.warn("idleTimeout is less than 10000ms, setting to default {}ms.", IDLE_TIMEOUT);
LOGGER.warn("{} - idleTimeout is less than 10000ms, setting to default {}ms.", poolName, IDLE_TIMEOUT);
idleTimeout = IDLE_TIMEOUT;
}
if (idleTimeout + TimeUnit.SECONDS.toMillis(1) > maxLifetime && maxLifetime > 0) {
LOGGER.warn("idleTimeout is close to or more than maxLifetime, disabling it.");
LOGGER.warn("{} - idleTimeout is close to or more than maxLifetime, disabling it.", poolName);
idleTimeout = 0;
}
if (maxLifetime == 0 && idleTimeout == 0) {
LOGGER.warn("setting idleTimeout to {}ms.", IDLE_TIMEOUT);
LOGGER.warn("{} - setting idleTimeout to {}ms.", poolName, IDLE_TIMEOUT);
idleTimeout = IDLE_TIMEOUT;
}
if (leakDetectionThreshold > 0 && !unitTest) {
if (leakDetectionThreshold < TimeUnit.SECONDS.toMillis(2) || (leakDetectionThreshold > maxLifetime && maxLifetime > 0)) {
LOGGER.warn("leakDetectionThreshold is less than 2000ms or more than maxLifetime, disabling it.");
LOGGER.warn("{} - leakDetectionThreshold is less than 2000ms or more than maxLifetime, disabling it.", poolName);
leakDetectionThreshold = 0L;
}
}
if (connectionTimeout != Integer.MAX_VALUE) {
if (validationTimeout > connectionTimeout) {
LOGGER.warn("validationTimeout should be less than connectionTimeout, setting validationTimeout to connectionTimeout.");
LOGGER.warn("{} - validationTimeout should be less than connectionTimeout, setting validationTimeout to connectionTimeout.", poolName);
validationTimeout = connectionTimeout;
}
if (maxLifetime > 0 && connectionTimeout > maxLifetime) {
LOGGER.warn("connectionTimeout should be less than maxLifetime, setting connectionTimeout to maxLifetime.");
LOGGER.warn("{} - connectionTimeout should be less than maxLifetime, setting connectionTimeout to maxLifetime.", poolName);
connectionTimeout = maxLifetime;
}
}

@ -63,7 +63,7 @@ import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
*/
public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateListener
{
private static final Logger LOGGER = LoggerFactory.getLogger(HikariPool.class);
private final Logger LOGGER = LoggerFactory.getLogger(HikariPool.class);
private static final ClockSource clockSource = ClockSource.INSTANCE;
@ -116,11 +116,11 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
checkFailFast();
ThreadFactory threadFactory = config.getThreadFactory();
this.addConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), "Hikari connection adder (pool " + poolName + ")", threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.closeConnectionExecutor = createThreadPoolExecutor(1 + (config.getMaximumPoolSize() / 2), "Hikari connection closer (pool " + poolName + ")", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
this.addConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection adder", threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.closeConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection closer", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
if (config.getScheduledExecutorService() == null) {
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("Hikari housekeeper (pool " + poolName + ")", true);
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory(poolName + " housekeeper", true);
this.houseKeepingExecutorService = new ScheduledThreadPoolExecutor(1, threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.houseKeepingExecutorService.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
this.houseKeepingExecutorService.setRemoveOnCancelPolicy(true);
@ -167,7 +167,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
final long now = clockSource.currentTime();
if (poolEntry.isMarkedEvicted() || (clockSource.elapsedMillis(poolEntry.lastAccessed, now) > ALIVE_BYPASS_WINDOW_MS && !isConnectionAlive(poolEntry.connection))) {
closeConnection(poolEntry, "(connection is evicted or dead)"); // Throw away the dead connection and try again
closeConnection(poolEntry, "(connection is evicted or dead)"); // Throw away the dead connection (passed max age or failed alive test)
timeout = hardTimeout - clockSource.elapsedMillis(startTime);
}
else {
@ -223,7 +223,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
connectionBag.close();
final ExecutorService assassinExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), "Hikari connection assassin (pool " + poolName + ")",
final ExecutorService assassinExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection assassinator",
config.getThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
try {
final long start = clockSource.currentTime();
@ -243,10 +243,9 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
}
finally {
logPoolState("After closing ");
LOGGER.info("{} - Closed.", poolName);
unregisterMBeans();
metricsTracker.close();
LOGGER.info("{} - Closed.", poolName);
}
}
@ -338,7 +337,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
public void softEvictConnections()
{
for (PoolEntry poolEntry : connectionBag.values()) {
softEvictConnection(poolEntry, "(connection evicted by user)", false /* not owner */);
softEvictConnection(poolEntry, "(connection evicted)", false /* not owner */);
}
}
@ -400,7 +399,8 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
/**
* Permanently close the real (underlying) connection (eat any exception).
*
* @param poolEntry the connection to actually close
* @param poolEntry poolEntry having the connection to close
* @param closureReason reason to close
*/
final void closeConnection(final PoolEntry poolEntry, final String closureReason)
{

@ -363,7 +363,7 @@ abstract class PoolBase
connection.isValid(1);
}
catch (Throwable e) {
LOGGER.warn("{} - Failed to execute isValid() for connection, configure connection test query. ({})", poolName, e.getMessage());
LOGGER.error("{} - Failed to execute isValid() for connection, configure connection test query. ({})", poolName, e.getMessage());
throw e;
}
}
@ -372,7 +372,7 @@ abstract class PoolBase
executeSql(connection, config.getConnectionTestQuery(), false, isIsolateInternalQueries && !isAutoCommit);
}
catch (Throwable e) {
LOGGER.warn("{} - Failed to execute connection test query. ({})", poolName, e.getMessage());
LOGGER.error("{} - Failed to execute connection test query. ({})", poolName, e.getMessage());
throw e;
}
}
@ -485,10 +485,10 @@ abstract class PoolBase
}
else {
ThreadFactory threadFactory = config.getThreadFactory();
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("Hikari JDBC-timeout executor", true);
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory(poolName + " network timeout executor", true);
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(threadFactory);
executor.allowCoreThreadTimeOut(true);
executor.setKeepAliveTime(15, TimeUnit.SECONDS);
executor.allowCoreThreadTimeOut(true);
netTimeoutExecutor = executor;
}
}

@ -136,7 +136,7 @@ final class PoolEntry implements IConcurrentBagEntry
{
final long now = ClockSource.INSTANCE.currentTime();
return connection
+ ", borrowed " + ClockSource.INSTANCE.elapsedMillis(lastBorrowed, now) + "ms ago, "
+ ", borrowed " + ClockSource.INSTANCE.elapsedMillis(lastBorrowed, now) + "ms ago"
+ ", accessed " + ClockSource.INSTANCE.elapsedMillis(lastAccessed, now) + "ms ago, "
+ stateToString();
}

@ -49,6 +49,11 @@ public final class PropertyElf
return;
}
HikariConfig config = null;
if (target instanceof HikariConfig) {
config = (HikariConfig) target;
}
List<Method> methods = Arrays.asList(target.getClass().getMethods());
Enumeration<?> propertyNames = properties.propertyNames();
while (propertyNames.hasMoreElements()) {
@ -59,8 +64,7 @@ public final class PropertyElf
propValue = properties.get(key);
}
if (target instanceof HikariConfig && propName.startsWith("dataSource.")) {
HikariConfig config = (HikariConfig) target;
if (config != null && propName.startsWith("dataSource.")) {
config.addDataSourceProperty(propName.substring("dataSource.".length()), propValue);
}
else {

@ -45,13 +45,15 @@ public class ConnectionRaceConditionTest
@Override
public Exception call() throws Exception
{
Connection c2;
try {
c2 = ds.getConnection();
ds.evictConnection(c2);
}
catch (Exception e) {
ref.set(e);
if (ref.get() != null) {
Connection c2;
try {
c2 = ds.getConnection();
ds.evictConnection(c2);
}
catch (Exception e) {
ref.set(e);
}
}
return null;
}
@ -62,8 +64,7 @@ public class ConnectionRaceConditionTest
threadPool.awaitTermination(30, TimeUnit.SECONDS);
if (ref.get() != null) {
ref.get().fillInStackTrace();
LoggerFactory.getLogger(ConnectionRaceConditionTest.class).error("Submit1 task failed", ref.get());
LoggerFactory.getLogger(ConnectionRaceConditionTest.class).error("Task failed", ref.get());
Assert.fail("Task failed");
}
}

@ -87,6 +87,8 @@ public class ShutdownTest
}
};
threads[i].setDaemon(true);
}
for (int i = 0; i < 10; i++) {
threads[i].start();
}

Loading…
Cancel
Save