@Test public void testShutdown() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); pool.close(CloseMode.GRACEFUL); try { pool.lease("somehost", null); Assert.fail("IllegalStateException should have been thrown"); } catch (final IllegalStateException expected) { } // Ignored if shut down pool.release(new PoolEntry<String, HttpConnection>("somehost"), true); }
@Test(expected=IllegalArgumentException.class) public void testGetStatsInvalid() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); pool.getStats(null); }
@Test public void testSetMaxPerRoute() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); pool.setMaxPerRoute("somehost", 1); Assert.assertEquals(1, pool.getMaxPerRoute("somehost")); pool.setMaxPerRoute("somehost", 0); Assert.assertEquals(0, pool.getMaxPerRoute("somehost")); pool.setMaxPerRoute("somehost", -1); Assert.assertEquals(2, pool.getMaxPerRoute("somehost")); }
final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 10); pool.setMaxPerRoute("somehost", 2); pool.setMaxPerRoute("otherhost", 1); pool.setMaxTotal(3); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future3 = pool.lease("otherhost", null); pool.release(entry1, true); pool.release(entry2, true); pool.release(entry3, true); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(3, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); final Future<PoolEntry<String, HttpConnection>> future4 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future5 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future6 = pool.lease("otherhost", null); final Future<PoolEntry<String, HttpConnection>> future7 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future8 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future9 = pool.lease("otherhost", null); pool.release(entry4, true); pool.release(entry5, false); pool.release(entry6, true);
@Internal protected PoolingAsyncClientConnectionManager( final AsyncClientConnectionOperator connectionOperator, final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolReusePolicy poolReusePolicy, final TimeValue timeToLive) { this.connectionOperator = Args.notNull(connectionOperator, "Connection operator"); switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) { case STRICT: this.pool = new StrictConnPool<>( DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, poolReusePolicy, null); break; case LAX: this.pool = new LaxConnPool<>( DEFAULT_MAX_CONNECTIONS_PER_ROUTE, timeToLive, poolReusePolicy, null); break; default: throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy); } this.closed = new AtomicBoolean(false); }
@Test public void testLeaseRequestCanceled() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(1, 1); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null, Timeout.ofMilliseconds(0), null); Assert.assertTrue(future1.isDone()); final PoolEntry<String, HttpConnection> entry1 = future1.get(); Assert.assertNotNull(entry1); entry1.assignConnection(Mockito.mock(HttpConnection.class)); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null, Timeout.ofMilliseconds(0), null); future2.cancel(true); pool.release(entry1, true); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(1, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); }
@Test public void testCreateNewIfExpired() throws Exception { final HttpConnection conn1 = Mockito.mock(HttpConnection.class); final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null); Assert.assertTrue(future1.isDone()); final PoolEntry<String, HttpConnection> entry1 = future1.get(); Assert.assertNotNull(entry1); entry1.assignConnection(conn1); entry1.updateExpiry(TimeValue.of(1, TimeUnit.MILLISECONDS)); pool.release(entry1, true); Thread.sleep(200L); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null); Assert.assertTrue(future2.isDone()); Mockito.verify(conn1).close(CloseMode.GRACEFUL); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(0, totals.getAvailable()); Assert.assertEquals(1, totals.getLeased()); Assert.assertEquals(Collections.singleton("somehost"), pool.getRoutes()); final PoolStats stats = pool.getStats("somehost"); Assert.assertEquals(0, stats.getAvailable()); Assert.assertEquals(1, stats.getLeased()); }
final HttpConnection conn2 = Mockito.mock(HttpConnection.class); final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null); pool.release(entry1, true); pool.release(entry2, true); pool.closeExpired(); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(1, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); final PoolStats stats = pool.getStats("somehost"); Assert.assertEquals(1, stats.getAvailable()); Assert.assertEquals(0, stats.getLeased());
final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null); pool.release(entry1, true); pool.release(entry2, true); pool.closeIdle(TimeValue.of(50, TimeUnit.MILLISECONDS)); PoolStats totals = pool.getTotalStats(); Assert.assertEquals(1, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); PoolStats stats = pool.getStats("somehost"); Assert.assertEquals(1, stats.getAvailable()); Assert.assertEquals(0, stats.getLeased()); Assert.assertEquals(0, stats.getPending()); pool.closeIdle(TimeValue.of(-1, TimeUnit.MILLISECONDS)); totals = pool.getTotalStats(); Assert.assertEquals(0, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); stats = pool.getStats("somehost"); Assert.assertEquals(0, stats.getAvailable()); Assert.assertEquals(0, stats.getLeased());
@Test public void testEmptyPool() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 10); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(0, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); Assert.assertEquals(10, totals.getMax()); Assert.assertEquals(Collections.emptySet(), pool.getRoutes()); final PoolStats stats = pool.getStats("somehost"); Assert.assertEquals(0, stats.getAvailable()); Assert.assertEquals(0, stats.getLeased()); Assert.assertEquals(0, stats.getPending()); Assert.assertEquals(2, stats.getMax()); Assert.assertEquals("[leased: 0][available: 0][pending: 0]", pool.toString()); }
@Test public void testSetMaxInvalid() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); try { pool.setMaxTotal(-1); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException expected) { } try { pool.setMaxPerRoute(null, 1); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException expected) { } try { pool.setDefaultMaxPerRoute(-1); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException expected) { } }
@Test public void testLeaseRequestTimeout() throws Exception { final HttpConnection conn1 = Mockito.mock(HttpConnection.class); final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(1, 1); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null, Timeout.ofMilliseconds(0), null); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null, Timeout.ofMilliseconds(0), null); final Future<PoolEntry<String, HttpConnection>> future3 = pool.lease("somehost", null, Timeout.ofMilliseconds(10), null); Assert.assertTrue(future1.isDone()); final PoolEntry<String, HttpConnection> entry1 = future1.get(); Assert.assertNotNull(entry1); entry1.assignConnection(conn1); Assert.assertFalse(future2.isDone()); Assert.assertFalse(future3.isDone()); Thread.sleep(100); pool.validatePendingRequests(); Assert.assertFalse(future2.isDone()); Assert.assertTrue(future3.isDone()); }
@Test(expected = IllegalStateException.class) public void testReleaseUnknownEntry() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2); pool.release(new PoolEntry<String, HttpConnection>("somehost"), true); }
@Test public void testLeaseIllegal() throws Exception { final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 10); try { pool.lease(null, null, Timeout.ZERO_MILLISECONDS, null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException expected) { } try { pool.lease("somehost", null, null, null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException expected) { } }
@Override public void close() { close(CloseMode.GRACEFUL); }
public Future<PoolEntry<T, C>> lease(final T route, final Object state) { return lease(route, state, Timeout.DISABLED, null); }
private void fireCallbacks() { LeaseRequest<T, C> request; while ((request = this.completedRequests.poll()) != null) { final BasicFuture<PoolEntry<T, C>> future = request.getFuture(); final Exception ex = request.getException(); final PoolEntry<T, C> result = request.getResult(); boolean successfullyCompleted = false; if (ex != null) { future.failed(ex); } else if (result != null) { if (future.completed(result)) { successfullyCompleted = true; } } else { future.cancel(); } if (!successfullyCompleted) { release(result, true); } } }
final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 10); pool.setMaxPerRoute("somehost", 2); pool.setMaxTotal(2); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null); PoolStats totals = pool.getTotalStats(); Assert.assertEquals(0, totals.getAvailable()); Assert.assertEquals(2, totals.getLeased()); pool.release(entry1, true); entry2.updateState("some-stuff"); pool.release(entry2, true); final Future<PoolEntry<String, HttpConnection>> future3 = pool.lease("somehost", "some-stuff"); final Future<PoolEntry<String, HttpConnection>> future4 = pool.lease("somehost", "some-stuff"); pool.release(entry3, true); pool.release(entry4, true); totals = pool.getTotalStats(); Assert.assertEquals(2, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); final Future<PoolEntry<String, HttpConnection>> future5 = pool.lease("somehost", "some-other-stuff"); totals = pool.getTotalStats();
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) { case STRICT: this.pool = new StrictConnPool<>( DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS,
@Test public void testLeaseRelease() throws Exception { final HttpConnection conn1 = Mockito.mock(HttpConnection.class); final HttpConnection conn2 = Mockito.mock(HttpConnection.class); final HttpConnection conn3 = Mockito.mock(HttpConnection.class); final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 10); final Future<PoolEntry<String, HttpConnection>> future1 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future2 = pool.lease("somehost", null); final Future<PoolEntry<String, HttpConnection>> future3 = pool.lease("otherhost", null); final PoolEntry<String, HttpConnection> entry1 = future1.get(); Assert.assertNotNull(entry1); entry1.assignConnection(conn1); final PoolEntry<String, HttpConnection> entry2 = future2.get(); Assert.assertNotNull(entry2); entry2.assignConnection(conn2); final PoolEntry<String, HttpConnection> entry3 = future3.get(); Assert.assertNotNull(entry3); entry3.assignConnection(conn3); pool.release(entry1, true); pool.release(entry2, true); pool.release(entry3, false); Mockito.verify(conn1, Mockito.never()).close(ArgumentMatchers.<CloseMode>any()); Mockito.verify(conn2, Mockito.never()).close(ArgumentMatchers.<CloseMode>any()); Mockito.verify(conn3, Mockito.times(1)).close(CloseMode.GRACEFUL); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(2, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); }