KeyedPoolImpl implements KeyedPool<K, T> { @Override public KeyedFuture<K, NoneType> shutdown() { synchronized (_mutex) { if ((_state == State.SHUTTING_DOWN) || (_state == State.SHUTDOWN)) { return _shutdownFuture; } _state = State.SHUTTING_DOWN; List<KeyedFuture<K, NoneType>> futureList = new ArrayList<KeyedFuture<K, NoneType>>(); for (Entry<K, AsyncPool<T>> poolEntry : _keyedPool.entrySet()) { AsyncResponseFuture<K, NoneType> shutdownFuture = new AsyncResponseFuture<K, NoneType>(poolEntry.getKey(), "Shutdown future for pool entry " + poolEntry.getKey()); poolEntry.getValue().shutdown(shutdownFuture); futureList.add(shutdownFuture); Collection<Callback<T>> waiters = poolEntry.getValue().cancelWaiters(); if ((null != waiters) && !waiters.isEmpty()) { Exception ex = new Exception("Pool is shutting down !!"); for (Callback<T> w : waiters) { w.onError(ex); } poolEntry.getValue().shutdown(shutdownFuture); } } _shutdownFuture = new CompositeFuture<K, NoneType>("Shutdown For Pool", GatherModeOnError.AND); _shutdownFuture.start(futureList); _shutdownFuture.addListener(new Runnable() { @Override public void run() { synchronized (_mutex) { _state = State.SHUTDOWN; } } }, null); } return _shutdownFuture; } KeyedPoolImpl(int minResourcesPerKey, int maxResourcesPerKey, long idleTimeoutMs,
      int maxPendingCheckoutRequests, PooledResourceManager<K, T> resourceManager,
      ScheduledExecutorService timeoutExecutorService, ExecutorService executorService, MetricsRegistry registry); @Override void start(); @Override KeyedFuture<K, T> checkoutObject(K key); @Override void checkinObject(K key, T object); @Override void destroyObject(K key, T object); @Override KeyedFuture<K, NoneType> shutdown(); @Override PoolStats<Histogram> getStats();  }
@Test public void testShutdown() throws Exception { ScheduledExecutorService timedExecutor = new ScheduledThreadPoolExecutor(1); ExecutorService service = MoreExecutors.sameThreadExecutor(); int numKeys = 5; int numResourcesPerKey = 5; TestResourceManager rm = new TestResourceManager(buildCreateMap(numKeys, numResourcesPerKey), null, null, null); KeyedPool<String, String> kPool = new KeyedPoolImpl<String, String>(5, 5, 1000 * 60 * 60L, 100, rm, timedExecutor, service, null); kPool.start(); AggregatedPoolStats s = (AggregatedPoolStats) kPool.getStats(); int c = 1; for (int j = 0; j < numResourcesPerKey; j++) { for (int i = 0; i < numKeys; i++) { KeyedFuture<String, String> rFuture = kPool.checkoutObject(getKey(i)); String resource = rFuture.getOne(); Assert.assertEquals(resource, getResource(i, j)); s.refresh(); Assert.assertEquals(s.getCheckedOut(), c++); } } s = (AggregatedPoolStats) kPool.getStats(); Assert.assertEquals(s.getTotalCreated(), numKeys * numResourcesPerKey); int checkedOut = c - 1; for (int j = 0; j < numResourcesPerKey; j++) { for (int i = 0; i < numKeys; i++) { kPool.checkinObject(getKey(i), getResource(i, j)); s.refresh(); Assert.assertEquals(s.getCheckedOut(), --checkedOut); } } c = 1; for (int i = 0; i < numKeys; i++) { KeyedFuture<String, String> rFuture = kPool.checkoutObject(getKey(i)); String resource = rFuture.getOne(); Assert.assertEquals(resource, getResource(i, 0)); s.refresh(); Assert.assertEquals(s.getCheckedOut(), c); c++; } Assert.assertEquals(s.getPoolSize(), numKeys * numResourcesPerKey); Assert.assertEquals(s.getIdleCount(), (numKeys * numResourcesPerKey) - 5); Future<Map<String, NoneType>> f = kPool.shutdown(); FutureReader<Map<String, NoneType>> reader = new FutureReader<Map<String, NoneType>>(f); reader.start(); reader.getBeginLatch().await(); Assert.assertTrue(reader.isStarted()); Assert.assertFalse(reader.isDone()); Assert.assertEquals(rm.getDestroyedMap().keySet().size(), 0); int d = 0; for (int i = 0; i < numKeys; i++) { if ((i % 2) == 0) { kPool.destroyObject(getKey(i), getResource(i, 0)); s.refresh(); Assert.assertEquals(s.getTotalDestroyed(), ++d); } else { kPool.checkinObject(getKey(i), getResource(i, 0)); } } s.refresh(); Assert.assertEquals(s.getTotalDestroyed(), 3); f.get(); reader.getEndLatch().await(); Assert.assertTrue(reader.isDone()); Future<Map<String, NoneType>> f2 = kPool.shutdown(); f2.get(); Map<String, List<String>> destroyedMap = rm.getDestroyedMap(); Assert.assertEquals(destroyedMap.keySet().size(), numKeys); for (int i = 0; i < numKeys; i++) { List<String> r = destroyedMap.get(getKey(i)); Assert.assertEquals(r.size(), numResourcesPerKey, "Resource for Key (" + getKey(i) + ")"); for (int j = 0; j < numResourcesPerKey; j++) { Assert.assertTrue(r.contains(getResource(i, j))); } } }