/* See LICENSE for licensing and NOTICE for copyright. */ package org.ldaptive.pool; import java.util.NoSuchElementException; import org.ldaptive.Connection; import org.ldaptive.DefaultConnectionFactory; /** * Implements a pool of connections that has a set minimum and maximum size. The pool will grow beyond it's maximum size * as necessary based on it's current load. Pool size will return to it's minimum based on the configuration of the * prune strategy. See {@link PruneStrategy}. This implementation should be used when you have some flexibility in the * number of connections that can be created to handle spikes in load. See {@link AbstractConnectionPool}. Note that * this pool will begin blocking if it cannot create new connections. * * @author Middleware Services */ public class SoftLimitConnectionPool extends BlockingConnectionPool { /** Creates a new soft limit pool. */ public SoftLimitConnectionPool() {} /** * Creates a new soft limit pool. * * @param cf connection factory */ public SoftLimitConnectionPool(final DefaultConnectionFactory cf) { super(new PoolConfig(), cf); } /** * Creates a new soft limit pool. * * @param pc pool configuration * @param cf connection factory */ public SoftLimitConnectionPool(final PoolConfig pc, final DefaultConnectionFactory cf) { super(pc, cf); } @Override public Connection getConnection() throws PoolException { throwIfNotInitialized(); PooledConnectionProxy pc = null; logger.trace("waiting on pool lock for check out {}", poolLock.getQueueLength()); poolLock.lock(); try { // if an available connection exists, use it // if no available connections, attempt to create if (!available.isEmpty()) { try { logger.trace("retrieve available connection"); pc = retrieveAvailableConnection(); } catch (NoSuchElementException e) { logger.error("could not remove connection from list", e); throw new IllegalStateException("Pool is empty", e); } } } finally { poolLock.unlock(); } if (pc == null) { // no connection was available, create a new one pc = createActiveConnection(); if (pc == null) { if (available.isEmpty() && active.isEmpty()) { logger.error("Could not service check out request"); throw new PoolExhaustedException("Pool is empty and connection creation failed"); } logger.debug("create failed, block until a connection is available"); pc = blockAvailableConnection(); } else { logger.trace("created new active connection: {}", pc); } } if (pc != null) { activateAndValidateConnection(pc); } else { logger.error("Could not service check out request"); throw new PoolExhaustedException("Pool is empty and connection creation failed"); } return createConnectionProxy(pc); } }