public Channel poll(Uri uri, String virtualHost, ProxyServer proxy, ChannelPoolPartitioning connectionPoolPartitioning) { Object partitionKey = connectionPoolPartitioning.getPartitionKey(uri, virtualHost, proxy); return channelPool.poll(partitionKey); }
@Override public KeepAliveStrategy getKeepAliveStrategy() { return new DefaultKeepAliveStrategy(); }
public void removeAll(Channel connection) { channelPool.removeAll(connection); }
final CountDownLatch latch = new CountDownLatch(16); for (int i = 0; i < 16; i++) { client.prepareGet(getTargetUrl()).execute(new AsyncCompletionHandlerBase() { @Override public Response onCompleted(Response response) throws Exception { client.prepareGet(getTargetUrl()).execute(new AsyncCompletionHandlerBase() { @Override public void onThrowable(Throwable t) {
@Override public boolean keepAlive(Request ahcRequest, HttpRequest request, HttpResponse response) { // Close connection upon a server error or per HTTP spec return (response.status().code() / 100 != 5) && super.keepAlive(ahcRequest, request, response); } });
public boolean isOpen() { return channelPool.isOpen(); } }
private void doClose() { openChannels.close(); channelPool.destroy(); }
@Override public void flushChannelPoolPartitions(Predicate<Object> predicate) { getChannelPool().flushPartitions(predicate); }
public Object getPartitionKey() { return connectionPoolPartitioning.getPartitionKey(targetRequest.getUri(), targetRequest.getVirtualHost(), proxyServer); }
public ClientStats getClientStats() { Map<String, Long> totalConnectionsPerHost = openChannels.stream().map(Channel::remoteAddress).filter(a -> a.getClass() == InetSocketAddress.class) .map(a -> (InetSocketAddress) a).map(InetSocketAddress::getHostName).collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); Map<String, Long> idleConnectionsPerHost = channelPool.getIdleChannelCountPerHost(); Map<String, HostStats> statsPerHost = totalConnectionsPerHost.entrySet().stream().collect(Collectors.toMap(Entry::getKey, entry -> { final long totalConnectionCount = entry.getValue(); final long idleConnectionCount = idleConnectionsPerHost.getOrDefault(entry.getKey(), 0L); final long activeConnectionCount = totalConnectionCount - idleConnectionCount; return new HostStats(activeConnectionCount, idleConnectionCount); })); return new ClientStats(statsPerHost); }
public final void tryToOfferChannelToPool(Channel channel, AsyncHandler<?> asyncHandler, boolean keepAlive, Object partitionKey) { if (channel.isActive() && keepAlive) { LOGGER.debug("Adding key: {} for channel {}", partitionKey, channel); Channels.setDiscard(channel); try { asyncHandler.onConnectionOffer(channel); } catch (Exception e) { LOGGER.error("onConnectionOffer crashed", e); } if (!channelPool.offer(channel, partitionKey)) { // rejected by pool closeChannel(channel); } } else { // not offered closeChannel(channel); } }
@Override @BeforeClass public void setUpGlobal() throws Exception { server = new Server(); ServerConnector connector = addHttpConnector(server); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); server.setHandler(context); context.addServlet(new ServletHolder(new MockTimeoutHttpServlet()), "/timeout/*"); server.start(); port1 = connector.getLocalPort(); }
public Object getPartitionKey(Uri uri, String virtualHost, ProxyServer proxyServer) { String targetHostBaseUrl = uri.getBaseUrl(); if (proxyServer == null) { if (virtualHost == null) { return targetHostBaseUrl; } else { return new CompositePartitionKey( targetHostBaseUrl, virtualHost, null, 0, null); } } else { return new CompositePartitionKey( targetHostBaseUrl, virtualHost, proxyServer.getHost(), uri.isSecured() && proxyServer.getProxyType() == ProxyType.HTTP ? proxyServer.getSecuredPort() : proxyServer.getPort(), proxyServer.getProxyType()); } } }
private void handleHttpResponse(final HttpResponse response, final Channel channel, final NettyResponseFuture<?> future, AsyncHandler<?> handler) throws Exception { HttpRequest httpRequest = future.getNettyRequest().getHttpRequest(); logger.debug("\n\nRequest {}\n\nResponse {}\n", httpRequest, response); future.setKeepAlive(config.getKeepAliveStrategy().keepAlive(future.getTargetRequest(), httpRequest, response)); NettyResponseStatus status = new NettyResponseStatus(future.getUri(), response, channel); HttpHeaders responseHeaders = response.headers(); if (!interceptors.exitAfterIntercept(channel, future, handler, response, status, responseHeaders)) { boolean abort = abortAfterHandlingStatus(handler, status) || // abortAfterHandlingHeaders(handler, responseHeaders) || // abortAfterHandlingReactiveStreams(channel, future, handler); if (abort) { finishUpdate(future, channel, true); } } }
/** * This test just make sure the hack used to catch disconnected channel under win7 doesn't throw any exception. The onComplete method must be only called once. * * @throws Exception if something wrong happens. */ @Test public void win7DisconnectTest() throws Exception { final AtomicInteger count = new AtomicInteger(0); try (AsyncHttpClient client = asyncHttpClient()) { AsyncCompletionHandler<Response> handler = new AsyncCompletionHandlerAdapter() { @Override public Response onCompleted(Response response) throws Exception { count.incrementAndGet(); StackTraceElement e = new StackTraceElement("sun.nio.ch.SocketDispatcher", "read0", null, -1); IOException t = new IOException(); t.setStackTrace(new StackTraceElement[]{e}); throw t; } }; try { client.prepareGet(getTargetUrl()).execute(handler).get(); fail("Must have received an exception"); } catch (ExecutionException ex) { assertNotNull(ex); assertNotNull(ex.getCause()); assertEquals(ex.getCause().getClass(), IOException.class); assertEquals(count.get(), 1); } } }
@Test public void testMaxTotalConnections() throws Exception { try (AsyncHttpClient client = asyncHttpClient(config().setKeepAlive(true).setMaxConnections(1))) { String url = getTargetUrl(); int i; Exception exception = null; for (i = 0; i < 3; i++) { try { logger.info("{} requesting url [{}]...", i, url); Response response = client.prepareGet(url).execute().get(); logger.info("{} response [{}].", i, response); } catch (Exception ex) { exception = ex; } } assertNull(exception); } }
@Test(expectedExceptions = TooManyConnectionsException.class) public void testMaxTotalConnectionsException() throws Throwable { try (AsyncHttpClient client = asyncHttpClient(config().setKeepAlive(true).setMaxConnections(1))) { String url = getTargetUrl(); List<ListenableFuture<Response>> futures = new ArrayList<>(); for (int i = 0; i < 5; i++) { logger.info("{} requesting url [{}]...", i, url); futures.add(client.prepareGet(url).execute()); } Exception exception = null; for (ListenableFuture<Response> future : futures) { try { future.get(); } catch (Exception ex) { exception = ex; break; } } assertNotNull(exception); throw exception.getCause(); } }
@Test public void nonPoolableConnectionReleaseSemaphoresTest() throws Throwable { RequestBuilder request = get(getTargetUrl()).setHeader("Connection", "close"); try (AsyncHttpClient client = asyncHttpClient(config().setMaxConnections(6).setMaxConnectionsPerHost(3))) { client.executeRequest(request).get(); Thread.sleep(1000); client.executeRequest(request).get(); Thread.sleep(1000); client.executeRequest(request).get(); Thread.sleep(1000); client.executeRequest(request).get(); } }
@Test public void multipleMaxConnectionOpenTestWithQuery() throws Exception { try (AsyncHttpClient c = asyncHttpClient(config().setKeepAlive(true).setConnectTimeout(5000).setMaxConnections(1))) { String body = "hello there"; // once Response response = c.preparePost(getTargetUrl() + "?foo=bar").setBody(body).execute().get(TIMEOUT, TimeUnit.SECONDS); assertEquals(response.getResponseBody(), "foo_" + body); // twice Exception exception = null; try { response = c.preparePost(getTargetUrl()).setBody(body).execute().get(TIMEOUT, TimeUnit.SECONDS); } catch (Exception ex) { ex.printStackTrace(); exception = ex; } assertNull(exception); assertNotNull(response); assertEquals(response.getStatusCode(), 200); } }
@Test(expectedExceptions = TooManyConnectionsException.class) public void multipleMaxConnectionOpenTest() throws Throwable { try (AsyncHttpClient c = asyncHttpClient(config().setKeepAlive(true).setConnectTimeout(5000).setMaxConnections(1))) { String body = "hello there"; // once Response response = c.preparePost(getTargetUrl()).setBody(body).execute().get(TIMEOUT, TimeUnit.SECONDS); assertEquals(response.getResponseBody(), body); // twice Exception exception = null; try { c.preparePost(String.format("http://localhost:%d/foo/test", port2)).setBody(body).execute().get(TIMEOUT, TimeUnit.SECONDS); fail("Should throw exception. Too many connections issued."); } catch (Exception ex) { ex.printStackTrace(); exception = ex; } assertNotNull(exception); throw exception.getCause(); } }