|
|
|
@ -16,17 +16,27 @@
|
|
|
|
|
|
|
|
|
|
package com.zaxxer.hikari.pool;
|
|
|
|
|
|
|
|
|
|
import static com.zaxxer.hikari.pool.PoolEntry.LASTACCESS_COMPARABLE;
|
|
|
|
|
import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_IN_USE;
|
|
|
|
|
import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_NOT_IN_USE;
|
|
|
|
|
import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_REMOVED;
|
|
|
|
|
import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor;
|
|
|
|
|
import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
|
|
|
|
|
import static java.util.Collections.unmodifiableCollection;
|
|
|
|
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
|
|
|
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
|
|
|
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
import java.sql.SQLTransientConnectionException;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.concurrent.Callable;
|
|
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
import java.util.concurrent.Future;
|
|
|
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
|
|
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
|
|
|
import java.util.concurrent.ThreadFactory;
|
|
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
@ -50,13 +60,6 @@ import com.zaxxer.hikari.util.ConcurrentBag.IBagStateListener;
|
|
|
|
|
import com.zaxxer.hikari.util.SuspendResumeLock;
|
|
|
|
|
import com.zaxxer.hikari.util.UtilityElf.DefaultThreadFactory;
|
|
|
|
|
|
|
|
|
|
import static com.zaxxer.hikari.pool.PoolEntry.LASTACCESS_COMPARABLE;
|
|
|
|
|
import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_IN_USE;
|
|
|
|
|
import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_NOT_IN_USE;
|
|
|
|
|
import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_REMOVED;
|
|
|
|
|
import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor;
|
|
|
|
|
import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This is the primary connection pool class that provides the basic
|
|
|
|
|
* pooling behavior for HikariCP.
|
|
|
|
@ -80,6 +83,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
|
|
|
|
|
|
|
|
|
|
private final PoolEntryCreator POOL_ENTRY_CREATOR = new PoolEntryCreator();
|
|
|
|
|
private final AtomicInteger totalConnections;
|
|
|
|
|
private final Collection<Runnable> addConnectionQueue;
|
|
|
|
|
private final ThreadPoolExecutor addConnectionExecutor;
|
|
|
|
|
private final ThreadPoolExecutor closeConnectionExecutor;
|
|
|
|
|
private final ScheduledThreadPoolExecutor houseKeepingExecutorService;
|
|
|
|
@ -118,6 +122,9 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
|
|
|
|
|
registerMBeans(this);
|
|
|
|
|
|
|
|
|
|
ThreadFactory threadFactory = config.getThreadFactory();
|
|
|
|
|
|
|
|
|
|
LinkedBlockingQueue<Runnable> addConnectionQueue = new LinkedBlockingQueue<>(config.getMaximumPoolSize() + 1);
|
|
|
|
|
this.addConnectionQueue = unmodifiableCollection(addConnectionQueue);
|
|
|
|
|
this.addConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection adder", threadFactory, new ThreadPoolExecutor.DiscardPolicy());
|
|
|
|
|
this.closeConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection closer", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
|
|
|
|
|
|
|
|
|
@ -297,7 +304,12 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
|
|
|
|
|
@Override
|
|
|
|
|
public Future<Boolean> addBagItem()
|
|
|
|
|
{
|
|
|
|
|
return addConnectionExecutor.submit(POOL_ENTRY_CREATOR);
|
|
|
|
|
final int connectionsToAdd = connectionBag.getPendingQueue() - addConnectionQueue.size();
|
|
|
|
|
if (connectionsToAdd > 0) {
|
|
|
|
|
return addConnectionExecutor.submit(POOL_ENTRY_CREATOR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CompletableFuture.completedFuture(Boolean.TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***********************************************************************
|
|
|
|
@ -461,9 +473,9 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
|
|
|
|
|
private void fillPool()
|
|
|
|
|
{
|
|
|
|
|
final int connectionsToAdd = Math.min(config.getMaximumPoolSize() - totalConnections.get(), config.getMinimumIdle() - getIdleConnections())
|
|
|
|
|
- addConnectionExecutor.getQueue().size();
|
|
|
|
|
- addConnectionQueue.size();
|
|
|
|
|
for (int i = 0; i < connectionsToAdd; i++) {
|
|
|
|
|
addBagItem();
|
|
|
|
|
addConnectionExecutor.submit(POOL_ENTRY_CREATOR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (connectionsToAdd > 0 && LOGGER.isDebugEnabled()) {
|
|
|
|
|