Minor cleanup.

pull/192/head
Brett Wooldridge 10 years ago
parent b23dc8bbaa
commit 9ba1f277cc

@ -64,45 +64,36 @@ import com.zaxxer.hikari.util.PoolUtilities;
*/ */
public final class HikariPool implements HikariPoolMBean, IBagStateListener public final class HikariPool implements HikariPoolMBean, IBagStateListener
{ {
private static final Logger LOGGER; private static final Logger LOGGER = LoggerFactory.getLogger(HikariPool.class);
private static final LeakTask NO_LEAK;
public final String catalog; public final String catalog;
public final boolean isAutoCommit;
public final boolean isReadOnly; public final boolean isReadOnly;
public final boolean isAutoCommit;
public int transactionIsolation; public int transactionIsolation;
private final DataSource dataSource; private final DataSource dataSource;
private final IConnectionCustomizer connectionCustomizer;
private final HikariConfig configuration; private final HikariConfig configuration;
private final ConcurrentBag<PoolBagEntry> connectionBag; private final IMetricsTracker metricsTracker;
private final ThreadPoolExecutor addConnectionExecutor; private final ThreadPoolExecutor addConnectionExecutor;
private final ConcurrentBag<PoolBagEntry> connectionBag;
private final ThreadPoolExecutor closeConnectionExecutor; private final ThreadPoolExecutor closeConnectionExecutor;
private final IMetricsTracker metricsTracker; private final IConnectionCustomizer connectionCustomizer;
private final AtomicReference<Throwable> lastConnectionFailure;
private final AtomicInteger totalConnections; private final AtomicInteger totalConnections;
private final AtomicReference<Throwable> lastConnectionFailure;
private final ScheduledThreadPoolExecutor houseKeepingExecutorService; private final ScheduledThreadPoolExecutor houseKeepingExecutorService;
private final boolean isIsolateInternalQueries; private final String username;
private final String password;
private final boolean isRecordMetrics; private final boolean isRecordMetrics;
private final boolean isRegisteredMbeans; private final boolean isRegisteredMbeans;
private final boolean isJdbc4ConnectionTest; private final boolean isJdbc4ConnectionTest;
private final boolean isIsolateInternalQueries;
private final long leakDetectionThreshold; private final long leakDetectionThreshold;
private final String username;
private final String password;
private volatile long connectionTimeout;
private volatile boolean isShutdown; private volatile boolean isShutdown;
private volatile long connectionTimeout;
// static initializer
static {
LOGGER = LoggerFactory.getLogger(HikariPool.class);
NO_LEAK = new LeakTask() {
public void cancel() {};
};
}
/** /**
* Construct a HikariPool with the specified configuration. * Construct a HikariPool with the specified configuration.
@ -173,7 +164,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
public Connection getConnection() throws SQLException public Connection getConnection() throws SQLException
{ {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
final MetricsContext context = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT); final MetricsContext metricsContext = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT);
long timeout = connectionTimeout; long timeout = connectionTimeout;
try { try {
@ -190,8 +181,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
continue; continue;
} }
LeakTask leakTask = (leakDetectionThreshold == 0) ? NO_LEAK : new LeakTask(leakDetectionThreshold, houseKeepingExecutorService); final LeakTask leakTask = (leakDetectionThreshold == 0) ? LeakTask.NO_LEAK : new LeakTask(leakDetectionThreshold, houseKeepingExecutorService);
final IHikariConnectionProxy proxyConnection = ProxyFactory.getProxyConnection(this, bagEntry, leakTask); final IHikariConnectionProxy proxyConnection = ProxyFactory.getProxyConnection(this, bagEntry, leakTask);
if (isRecordMetrics) { if (isRecordMetrics) {
@ -206,12 +196,11 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
throw new SQLException("Interrupted during connection acquisition", e); throw new SQLException("Interrupted during connection acquisition", e);
} }
finally { finally {
context.stop(); metricsContext.stop();
} }
logPoolState("Timeout failure "); logPoolState("Timeout failure ");
throw new SQLException(String.format("Timeout of %dms encountered waiting for connection.", configuration.getConnectionTimeout()), throw new SQLException(String.format("Timeout of %dms encountered waiting for connection.", connectionTimeout), lastConnectionFailure.getAndSet(null));
lastConnectionFailure.getAndSet(null));
} }
/** /**
@ -430,14 +419,14 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
*/ */
private boolean addConnection() private boolean addConnection()
{ {
// Speculative increment of totalConnections with expectation of success
if (totalConnections.incrementAndGet() > configuration.getMaximumPoolSize() || isShutdown) {
totalConnections.decrementAndGet();
return true;
}
Connection connection = null; Connection connection = null;
try { try {
// Speculative increment of totalConnections with expectation of success
if (totalConnections.incrementAndGet() > configuration.getMaximumPoolSize() || isShutdown) {
totalConnections.decrementAndGet();
return true;
}
connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password); connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation); transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation);
connectionCustomizer.customize(connection); connectionCustomizer.customize(connection);

@ -31,11 +31,20 @@ import org.slf4j.LoggerFactory;
*/ */
public class LeakTask implements Runnable public class LeakTask implements Runnable
{ {
public static final LeakTask NO_LEAK;
private static final Logger LOGGER = LoggerFactory.getLogger(LeakTask.class); private static final Logger LOGGER = LoggerFactory.getLogger(LeakTask.class);
private final ScheduledFuture<?> scheduledFuture; private final ScheduledFuture<?> scheduledFuture;
private final Exception exception; private final Exception exception;
static
{
NO_LEAK = new LeakTask() {
@Override
public void cancel() {};
};
}
public LeakTask() public LeakTask()
{ {
scheduledFuture = null; scheduledFuture = null;

@ -63,45 +63,36 @@ import com.zaxxer.hikari.util.PoolUtilities;
*/ */
public final class HikariPool implements HikariPoolMBean, IBagStateListener public final class HikariPool implements HikariPoolMBean, IBagStateListener
{ {
private static final Logger LOGGER; private static final Logger LOGGER = LoggerFactory.getLogger(HikariPool.class);
private static final LeakTask NO_LEAK;
public final String catalog; public final String catalog;
public final boolean isAutoCommit;
public final boolean isReadOnly; public final boolean isReadOnly;
public final boolean isAutoCommit;
public int transactionIsolation; public int transactionIsolation;
private final DataSource dataSource; private final DataSource dataSource;
private final IConnectionCustomizer connectionCustomizer;
private final HikariConfig configuration; private final HikariConfig configuration;
private final ConcurrentBag<PoolBagEntry> connectionBag; private final IMetricsTracker metricsTracker;
private final ThreadPoolExecutor addConnectionExecutor; private final ThreadPoolExecutor addConnectionExecutor;
private final ConcurrentBag<PoolBagEntry> connectionBag;
private final ThreadPoolExecutor closeConnectionExecutor; private final ThreadPoolExecutor closeConnectionExecutor;
private final IMetricsTracker metricsTracker; private final IConnectionCustomizer connectionCustomizer;
private final AtomicReference<Throwable> lastConnectionFailure;
private final AtomicInteger totalConnections; private final AtomicInteger totalConnections;
private final AtomicReference<Throwable> lastConnectionFailure;
private final ScheduledThreadPoolExecutor houseKeepingExecutorService; private final ScheduledThreadPoolExecutor houseKeepingExecutorService;
private final boolean isIsolateInternalQueries; private final String username;
private final String password;
private final boolean isRecordMetrics; private final boolean isRecordMetrics;
private final boolean isRegisteredMbeans; private final boolean isRegisteredMbeans;
private final boolean isJdbc4ConnectionTest; private final boolean isJdbc4ConnectionTest;
private final boolean isIsolateInternalQueries;
private final long leakDetectionThreshold; private final long leakDetectionThreshold;
private final String username;
private final String password;
private volatile long connectionTimeout;
private volatile boolean isShutdown; private volatile boolean isShutdown;
private volatile long connectionTimeout;
// static initializer
static {
LOGGER = LoggerFactory.getLogger(HikariPool.class);
NO_LEAK = new LeakTask() {
public void cancel() {};
};
}
/** /**
* Construct a HikariPool with the specified configuration. * Construct a HikariPool with the specified configuration.
@ -170,7 +161,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
public Connection getConnection() throws SQLException public Connection getConnection() throws SQLException
{ {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
final MetricsContext context = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT); final MetricsContext metricsContext = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT);
long timeout = connectionTimeout; long timeout = connectionTimeout;
try { try {
@ -187,8 +178,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
continue; continue;
} }
LeakTask leakTask = (leakDetectionThreshold == 0) ? NO_LEAK : new LeakTask(leakDetectionThreshold, houseKeepingExecutorService); final LeakTask leakTask = (leakDetectionThreshold == 0) ? LeakTask.NO_LEAK : new LeakTask(leakDetectionThreshold, houseKeepingExecutorService);
final IHikariConnectionProxy proxyConnection = ProxyFactory.getProxyConnection(this, bagEntry, leakTask); final IHikariConnectionProxy proxyConnection = ProxyFactory.getProxyConnection(this, bagEntry, leakTask);
if (isRecordMetrics) { if (isRecordMetrics) {
@ -203,12 +193,11 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
throw new SQLException("Interrupted during connection acquisition", e); throw new SQLException("Interrupted during connection acquisition", e);
} }
finally { finally {
context.stop(); metricsContext.stop();
} }
logPoolState("Timeout failure "); logPoolState("Timeout failure ");
throw new SQLException(String.format("Timeout of %dms encountered waiting for connection.", configuration.getConnectionTimeout()), throw new SQLException(String.format("Timeout of %dms encountered waiting for connection.", connectionTimeout), lastConnectionFailure.getAndSet(null));
lastConnectionFailure.getAndSet(null));
} }
/** /**
@ -417,13 +406,14 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
*/ */
private boolean addConnection() private boolean addConnection()
{ {
// Speculative increment of totalConnections with expectation of success
if (totalConnections.incrementAndGet() > configuration.getMaximumPoolSize() || isShutdown) {
totalConnections.decrementAndGet();
return true;
}
Connection connection = null; Connection connection = null;
try { try {
// Speculative increment of totalConnections with expectation of success
if (totalConnections.incrementAndGet() > configuration.getMaximumPoolSize() || isShutdown) {
totalConnections.decrementAndGet();
return true;
}
connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password); connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation); transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation);
@ -574,15 +564,13 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
final long idleTimeout = configuration.getIdleTimeout(); final long idleTimeout = configuration.getIdleTimeout();
connectionBag.values(STATE_NOT_IN_USE).forEach(bagEntry -> { connectionBag.values(STATE_NOT_IN_USE).stream().filter(p -> connectionBag.reserve(p)).forEach(bagEntry -> {
if (connectionBag.reserve(bagEntry)) { if ((idleTimeout > 0L && now > bagEntry.lastAccess + idleTimeout) || (now > bagEntry.expirationTime)) {
if ((idleTimeout > 0L && now > bagEntry.lastAccess + idleTimeout) || (now > bagEntry.expirationTime)) { closeConnection(bagEntry);
closeConnection(bagEntry); return;
return;
}
connectionBag.unreserve(bagEntry);
} }
connectionBag.unreserve(bagEntry);
}); });
logPoolState("After cleanup "); logPoolState("After cleanup ");

@ -31,11 +31,20 @@ import org.slf4j.LoggerFactory;
*/ */
public class LeakTask implements Runnable public class LeakTask implements Runnable
{ {
public static final LeakTask NO_LEAK;
private static final Logger LOGGER = LoggerFactory.getLogger(LeakTask.class); private static final Logger LOGGER = LoggerFactory.getLogger(LeakTask.class);
private final ScheduledFuture<?> scheduledFuture; private final ScheduledFuture<?> scheduledFuture;
private final Exception exception; private final Exception exception;
static
{
NO_LEAK = new LeakTask() {
@Override
public void cancel() {};
};
}
public LeakTask() public LeakTask()
{ {
scheduledFuture = null; scheduledFuture = null;

Loading…
Cancel
Save