public Connection getConnection() throws SQLException
{
acquisitionSemaphore.acquireUninterruptibly();
long timeout = connectionTimeout;
final long start = System.currentTimeMillis();
final MetricsContext metricsContext = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT);
try {
do {
final PoolBagEntry bagEntry = connectionBag.borrow(timeout, TimeUnit.MILLISECONDS);
if (bagEntry == null) {
break; // We timed out... break and throw exception
}
final long now = System.currentTimeMillis();
if (now > bagEntry.expirationTime || (now - bagEntry.lastAccess > ALIVE_BYPASS_WINDOW && !isConnectionAlive(bagEntry.connection, timeout))) {
closeConnection(bagEntry); // Throw away the dead connection and try again
timeout = connectionTimeout - elapsedTimeMs(start);
continue;
}
final LeakTask leakTask = (leakDetectionThreshold == 0) ? LeakTask.NO_LEAK : new LeakTask(leakDetectionThreshold, houseKeepingExecutorService);
final IHikariConnectionProxy proxyConnection = ProxyFactory.getProxyConnection(this, bagEntry, leakTask);
metricsContext.setConnectionLastOpen(bagEntry, now);
return proxyConnection;
}
while (timeout > 0L);
}
catch (InterruptedException e) {
throw new SQLException("Interrupted during connection acquisition", e);
}
finally {
acquisitionSemaphore.release();
metricsContext.stop();
}
logPoolState("Timeout failure ");
throw new SQLException(String.format("Timeout after %dms of waiting for a connection.", elapsedTimeMs(start)), lastConnectionFailure.getAndSet(null));
}