Description
If I download a file repeatedly using a single instance of CloseableHttpAsyncClient, the following exception is thrown after few requests
java.io.IOException: org.apache.hc.core5.http.ConnectionClosedException: Connection is closed
The following test app always ends up with a ConnectionClosedException after a number of requests
public class TestHTTP { public static void main(final String[] args) throws Exception { URI uri = new URI("http://127.0.0.1:8000/crls/test-ca-no-next-update.crl"); CloseableHttpAsyncClient client = HttpAsyncClients.createDefault(); client.start(); try { SimpleHttpRequest request = SimpleRequestBuilder.get(uri).build(); SimpleRequestProducer requestProducer = SimpleRequestProducer.create(request); SimpleResponseConsumer responseConsumer = SimpleResponseConsumer.create(); FutureCallback<SimpleHttpResponse> callback = new FutureCallback<SimpleHttpResponse>() { @Override public void completed(final SimpleHttpResponse response) { System.out.println("************** completed"); System.out.println(request + "->" + new StatusLine(response)); System.out.println(response.getBody()); } @Override public void failed(final Exception ex) { System.out.println("************** failed"); System.out.println(request + "->" + ex); } @Override public void cancelled() { System.out.println("************** canceled"); System.out.println(request + " cancelled"); } }; for (int i = 0; i < 10000; i++) { System.out.println("Request: " + i); Future<SimpleHttpResponse> future = client.execute( requestProducer, responseConsumer, callback); future.get(); //if sleep is enabled, no exception will be thrown //Thread.sleep(1); } } catch (ExecutionException e) { e.printStackTrace(); } finally { client.close(CloseMode.GRACEFUL); } } }
The full stack trace:
java.util.concurrent.ExecutionException: org.apache.hc.core5.http.ConnectionClosedException: Connection is closed at org.apache.hc.core5.concurrent.BasicFuture.getResult(BasicFuture.java:72) at org.apache.hc.core5.concurrent.BasicFuture.get(BasicFuture.java:85) at test.TestHTTP.main(TestHTTP.java:65) Caused by: org.apache.hc.core5.http.ConnectionClosedException: Connection is closed at org.apache.hc.core5.http.nio.command.CommandSupport.cancelCommands(CommandSupport.java:76) at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.onDisconnect(AbstractHttp1StreamDuplexer.java:409) at org.apache.hc.core5.http.impl.nio.AbstractHttp1IOEventHandler.disconnected(AbstractHttp1IOEventHandler.java:95) at org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler.disconnected(ClientHttp1IOEventHandler.java:39) at org.apache.hc.core5.reactor.InternalDataChannel.disconnected(InternalDataChannel.java:193) at org.apache.hc.core5.reactor.SingleCoreIOReactor.processClosedSessions(SingleCoreIOReactor.java:231) at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:133) at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:85) at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44) at java.base/java.lang.Thread.run(Thread.java:829)
The file that is downloaded is served by python http server running on localhost:
python3 -m http.server
If I add Thread.sleep, the exception will not happen.
For some reason it looks like the IOReactorWorker background thread closes the CloseableHttpAsyncClient
Any idea?