@Override public void close() { close(CloseMode.GRACEFUL); }
@Override public String toString() { final PoolStats totalStats = getTotalStats(); final StringBuilder buffer = new StringBuilder(); buffer.append("[leased: "); buffer.append(totalStats.getLeased()); buffer.append("][available: "); buffer.append(totalStats.getAvailable()); buffer.append("][pending: "); buffer.append(totalStats.getPending()); buffer.append("]"); return buffer.toString(); }
public Future<PoolEntry<T, C>> lease(final T route, final Object state) { return lease(route, state, Timeout.DISABLED, null); }
@Test public void testLeaseRequestCanceled() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(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 LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(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 LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(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());
@Test public void testShutdown() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(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); }
final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(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());
@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 testEmptyPool() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); final PoolStats totals = pool.getTotalStats(); Assert.assertEquals(0, totals.getAvailable()); Assert.assertEquals(0, totals.getLeased()); Assert.assertEquals(0, totals.getPending()); Assert.assertEquals(0, 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 testLeaseRequestTimeout() throws Exception { final HttpConnection conn1 = Mockito.mock(HttpConnection.class); final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(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 public void testLeaseIllegal() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); try { pool.lease(null, null, Timeout.ZERO_MILLISECONDS, null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException expected) { } }
@Test public void testSetMaxInvalid() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); 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(expected=IllegalArgumentException.class) public void testGetStatsInvalid() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); pool.getStats(null); }
@Test(expected = IllegalStateException.class) public void testReleaseUnknownEntry() throws Exception { final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); pool.release(new PoolEntry<String, HttpConnection>("somehost"), true); }
@Override public void closeExpired() { final long now = System.currentTimeMillis(); enumAvailable(new Callback<PoolEntry<T, C>>() { @Override public void execute(final PoolEntry<T, C> entry) { if (entry.getExpiryDeadline().isBefore(now)) { entry.discardConnection(CloseMode.GRACEFUL); } } }); }
@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 LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); 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()); }
break; case LAX: this.pool = new LaxConnPool<>( DEFAULT_MAX_CONNECTIONS_PER_ROUTE, timeToLive,
@Override public void closeExpired() { final long now = System.currentTimeMillis(); enumAvailable(new Callback<PoolEntry<T, C>>() { @Override public void execute(final PoolEntry<T, C> entry) { if (entry.getExpiryDeadline().isBefore(now)) { entry.discardConnection(CloseMode.GRACEFUL); } } }); }
final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2); pool.setMaxPerRoute("somehost", 2); pool.setMaxPerRoute("otherhost", 1); 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);