/** Removes a connection */ void removeItem(ManagedPoolItem item, ManagedConnection mConn) { synchronized (_connectionPool) { _idlePool.remove(mConn); _connectionPool.remove(item); _connectionPool.notifyAll(); } try { item.destroy(); } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); } }
/** Alarm listener. */ @Override public void handleAlarm(Alarm alarm) { if (!_lifecycle.isActive()) return; try { _alarmConnections.clear(); synchronized (_connectionPool) { _alarmConnections.addAll(_connectionPool); } for (int i = _alarmConnections.size() - 1; i >= 0; i--) { ManagedPoolItem item = _alarmConnections.get(i); if (!item.isValid()) item.destroy(); } _alarmConnections.clear(); fillIdlePool(); } finally { if (!_lifecycle.isActive()) { } else if (0 < _idleTimeout && _idleTimeout < 1000) _alarm.queue(1000); else if (1000 < _idleTimeout && _idleTimeout < 60000) _alarm.queue(_idleTimeout); else _alarm.queue(60000); } }
/** Starts creation of an overflow connection. */ private boolean startCreateOverflow() throws ResourceException { int size = _connectionPool.size(); int createCount = _createCount.incrementAndGet(); if (createCount + size <= _maxConnections + _maxOverflowConnections) return true; _createCount.decrementAndGet(); String message = L.l( "{0} cannot create overflow connection after {1}ms" + " (pool-size={2}" + ", max-connections={3}" + ", create-count={4}" + ", max-create-connections={5}" + ", max-overflow-connections={6})", this, _connectionWaitTimeout, _connectionPool.size(), _maxConnections, _createCount.get(), _maxCreateConnections, _maxOverflowConnections); HealthStatusService.updateCurrentHealthStatus(this, HealthStatus.WARNING, message); throw new ResourceException(message); }
/* * Removes a connection from the pool. */ public void markForPoolRemoval(ManagedConnection mConn) { synchronized (_connectionPool) { for (int i = _connectionPool.size() - 1; i >= 0; i--) { ManagedPoolItem poolItem = _connectionPool.get(i); if (poolItem.getManagedConnection() == mConn) { poolItem.setConnectionError(); return; } } } }
private ManagedPoolItem findPoolItem(ManagedConnection mConn) { synchronized (_connectionPool) { for (int i = _connectionPool.size() - 1; i >= 0; i--) { ManagedPoolItem testPoolItem = _connectionPool.get(i); if (testPoolItem.getManagedConnection() == mConn) { return testPoolItem; } } return null; } }
/** Adds a connection to the idle pool. */ void toIdle(ManagedPoolItem item) { try { if (_maxConnections < _connectionPool.size() || item.isConnectionError()) { return; } ManagedConnection mConn = item.getManagedConnection(); if (mConn == null) { return; } mConn.cleanup(); long now = CurrentTime.getCurrentTime(); if (_idlePool.size() == 0) _idlePoolExpire = now + _idleTimeout; if (_idlePoolExpire < now) { // shrink the idle pool when non-empty for idleTimeout _idlePoolExpire = now + _idleTimeout; } else if (_idlePool.add(mConn)) { item = null; return; } } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } finally { notifyConnectionAvailable(); if (item != null) item.destroy(); } }
/** Finds the pool item joined to this one. return null. */ ManagedPoolItem findJoin(UserTransactionImpl uTrans, ManagedPoolItem item) { if (!uTrans.isActive()) return null; ArrayList<ManagedXAResource> poolItems = uTrans.getXaResources(); int length = poolItems.size(); for (int i = 0; i < length; i++) { ManagedXAResource resource = poolItems.get(i); if (resource instanceof ManagedPoolItem) { ManagedPoolItem poolItem = (ManagedPoolItem) resource; if (poolItem.isJoin(item)) return poolItem; } } return null; }
/** Clears the idle connections in the pool. */ @Override public void clear() { ArrayList<ManagedPoolItem> pool = _connectionPool; if (pool == null) return; ArrayList<ManagedPoolItem> clearItems = new ArrayList<ManagedPoolItem>(); synchronized (_connectionPool) { _idlePool.clear(); clearItems.addAll(pool); pool.clear(); } for (int i = 0; i < clearItems.size(); i++) { ManagedPoolItem poolItem = clearItems.get(i); try { poolItem.destroy(); } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } } }
/** Allocates a resource matching the parameters. If none matches, return null. */ private UserPoolItem allocateShared( UserTransactionImpl transaction, ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info) { if (!transaction.isActive()) return null; ArrayList<ManagedXAResource> poolItems = transaction.getXaResources(); int length = poolItems.size(); for (int i = 0; i < length; i++) { ManagedXAResource xaResource = poolItems.get(i); if (xaResource instanceof ManagedPoolItem) { ManagedPoolItem poolItem = (ManagedPoolItem) xaResource; UserPoolItem item = poolItem.allocateXA(mcf, subject, info); if (item != null) return item; } } return null; }
/** Destroys the manager. */ public void destroy() { stop(); if (!_lifecycle.toDestroy()) return; ArrayList<ManagedPoolItem> pool; synchronized (_connectionPool) { pool = new ArrayList<ManagedPoolItem>(_connectionPool); _connectionPool.clear(); if (_idlePool != null) _idlePool.clear(); } for (int i = 0; i < pool.size(); i++) { ManagedPoolItem poolItem = pool.get(i); try { poolItem.destroy(); } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } } }
/** Creates a new connection. */ private UserPoolItem createConnection( ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info, UserPoolItem oldPoolItem) throws ResourceException { boolean isValid = false; ManagedPoolItem poolItem = null; try { ManagedConnection mConn = mcf.createManagedConnection(subject, info); if (mConn == null) throw new ResourceException( L.l("'{0}' did not return a connection from createManagedConnection", mcf)); poolItem = new ManagedPoolItem(this, mcf, mConn); UserPoolItem userPoolItem; // Ensure the connection is still valid userPoolItem = poolItem.toActive(subject, info, oldPoolItem); if (userPoolItem == null) { throw new ResourceException(L.l("Connection '{0}' was not valid on creation", poolItem)); } _connectionCreateCountTotal.incrementAndGet(); synchronized (_connectionPool) { _connectionPool.add(poolItem); } poolItem = null; isValid = true; return userPoolItem; } finally { if (!isValid) { _connectionFailCountTotal.incrementAndGet(); _lastFailTime = CurrentTime.getCurrentTime(); } // server/308b - connection removed on rollback-only, when it's // theoretically possible to reuse it if (poolItem != null) poolItem.destroy(); } }
private void fillIdlePool() { int count = _minIdleCount; try { while (_connectionPool.size() < _minIdleCount && count-- >= 0 && _lifecycle.isActive()) { Subject subject = null; ConnectionRequestInfo info = null; UserPoolItem userPoolItem; userPoolItem = createConnection(_mcf, subject, info, null); if (userPoolItem != null) userPoolItem.toIdle(); } } catch (Exception e) { e.printStackTrace(); log.log(Level.FINE, e.toString(), e); } }
/** True if a connection can be created, i.e. below max-connections and max-create-connections. */ private boolean isCreateAvailable() { return (_connectionPool.size() < _maxConnections && _createCount.get() < _maxCreateConnections); }
/** * Allocates the pool item for a connection, creating one if necessary. * * @param mcf the driver's ManagedConnectionFactory for creating pooled connections * @param subject the user's authentication credentials * @param info the user's extra connection information */ UserPoolItem allocatePoolConnection( ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info, UserPoolItem oldPoolItem) throws ResourceException { long expireTime = CurrentTime.getCurrentTimeActual() + _connectionWaitTimeout; if (!_lifecycle.isActive()) { throw new IllegalStateException( L.l("{0}: Can't allocate connection because the connection pool is closed.", this)); } do { UserPoolItem userPoolItem = allocateIdleConnection(mcf, subject, info, oldPoolItem); if (userPoolItem != null) return userPoolItem; // if no item in pool, try to create one if (startCreateConnection()) { try { return createConnection(mcf, subject, info, oldPoolItem); } finally { finishCreateConnection(); } } } while (_lifecycle.isActive() && waitForAvailableConnection(expireTime)); if (!_lifecycle.isActive()) throw new IllegalStateException( L.l("{0}: Can't allocate connection because the connection pool is closed.", this)); String message = (this + " pool throttled create timeout" + " (pool-size=" + _connectionPool.size() + ", max-connections=" + _maxConnections + ", create-count=" + _createCount.get() + ", max-create-connections=" + _maxCreateConnections + ")"); HealthStatusService.updateCurrentHealthStatus(this, HealthStatus.WARNING, message); if (startCreateOverflow()) { try { return createConnection(mcf, subject, info, oldPoolItem); } finally { finishCreateConnection(); } } message = (this + " pool overflow failed to create" + " (pool-size=" + _connectionPool.size() + ", max-connections=" + _maxConnections + ", create-count=" + _createCount.get() + ", max-create-connections=" + _maxCreateConnections + ")"); HealthStatusService.updateCurrentHealthStatus(this, HealthStatus.CRITICAL, message); throw new ResourceException( L.l("Can't create overflow connection connection-max={0}", _maxConnections)); }
/** Returns the active connections. */ @Override public int getConnectionActiveCount() { return _connectionPool.size() - _idlePool.size(); }
/** Returns the total connections. */ @Override public int getConnectionCount() { return _connectionPool.size(); }