private void waitForCompletion(long steps, ResourcePool oldPool, long totalWaitTime) throws InterruptedException { debug("waiting for in-use connections to return to pool or waiting requests to complete"); try { Object poolWaitQueue = oldPool.getPoolWaitQueue(); synchronized (poolWaitQueue) { long waitTime = totalWaitTime / steps; if (waitTime > 0) { poolWaitQueue.wait(waitTime); } } } catch (InterruptedException ie) { // ignore } debug("woke-up to verify in-use / waiting requests list"); }
private void handlePoolRecreation(final ConnectorConnectionPool connConnPool) throws ConnectorRuntimeException { debug("[DRC] Pool recreation required"); final long reconfigWaitTimeout = connConnPool.getDynamicReconfigWaitTimeout(); PoolInfo poolInfo = new PoolInfo( connConnPool.getName(), connConnPool.getApplicationName(), connConnPool.getModuleName()); final ResourcePool oldPool = runtime.getPoolManager().getPool(poolInfo); if (reconfigWaitTimeout > 0) { oldPool.blockRequests(reconfigWaitTimeout); if (oldPool.getPoolWaitQueue().getQueueLength() > 0 || oldPool.getPoolStatus().getNumConnUsed() > 0) { Runnable thread = new Runnable() { @Override public void run() { try { long numSeconds = 5000L; // poll every 5 seconds long steps = reconfigWaitTimeout / numSeconds; if (steps == 0) { waitForCompletion(steps, oldPool, reconfigWaitTimeout); } else { for (long i = 0; i < steps; i++) { waitForCompletion(steps, oldPool, reconfigWaitTimeout); if (oldPool.getPoolWaitQueue().getQueueLength() == 0 && oldPool.getPoolStatus().getNumConnUsed() == 0) { debug("wait-queue is empty and num-con-used is 0"); break; } } } handlePoolRecreationForExistingProxies(connConnPool); PoolWaitQueue reconfigWaitQueue = oldPool.getReconfigWaitQueue(); debug("checking reconfig-wait-queue for notification"); if (reconfigWaitQueue.getQueueContents().size() > 0) { for (Object o : reconfigWaitQueue.getQueueContents()) { debug("notifying reconfig-wait-queue object [ " + o + " ]"); synchronized (o) { o.notify(); } } } } catch (InterruptedException ie) { if (_logger.isLoggable(Level.FINEST)) { _logger.log( Level.FINEST, "Interrupted while waiting for all existing clients to return connections to pool", ie); } } if (_logger.isLoggable(Level.FINEST)) { _logger.finest( "woke-up after giving time for in-use connections to return, " + "WaitQueue-Length : [" + oldPool.getPoolWaitQueue().getQueueContents() + "], " + "Num-Conn-Used : [" + oldPool.getPoolStatus().getNumConnUsed() + "]"); } } }; Callable c = Executors.callable(thread); ArrayList list = new ArrayList(); list.add(c); try { execService.invokeAll(list); } catch (Exception e) { Object[] params = new Object[] {connConnPool.getName(), e}; _logger.log(Level.WARNING, "exception.redeploying.pool.transparently", params); } } else { handlePoolRecreationForExistingProxies(connConnPool); } } else if (oldPool.getReconfigWaitTime() > 0) { // reconfig is being switched off, invalidate proxies Collection<BindableResource> resources = JdbcResourcesUtil.getResourcesOfPool( runtime.getResources(oldPool.getPoolInfo()), oldPool.getPoolInfo().getName()); ConnectorRegistry registry = ConnectorRegistry.getInstance(); for (BindableResource resource : resources) { ResourceInfo resourceInfo = ConnectorsUtil.getResourceInfo(resource); registry.removeResourceFactories(resourceInfo); } // recreate the pool now. recreatePool(connConnPool); } else { recreatePool(connConnPool); } }