[ 
https://issues.apache.org/jira/browse/HTTPASYNC-152?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16966562#comment-16966562
 ] 

Anurag Agarwal commented on HTTPASYNC-152:
------------------------------------------

[~olegk] this may be slightly different from the above issue, but I noticed 
that at certain places where in catch clause the session is being closed, it is 
not removed from the sessions Set, do you think there is a possible memory leak.

Take the second scenario above, after the fix from PR 157, the session will be 
correctly terminated and CancelledKeyException will be thrown.

This error is then catched and the session is closed, but the instance has 
already been added to the sessions Set before and it is not removed from here 
until the IOReactor is shutdown, thus the instance is never fully dereferenced 
from the application.

Similar things can be found at rest of the places where session.close() is 
called.

If that is the case, closing the session from another method will not work as 
well like in 
https://github.com/apache/httpcomponents-core/commit/a5defd98653b627a6bbf866895b96b56976dfb53
 as it will still leave a reference leading to memory leak.

> "Connection must be created by connection manager" raised when requests are 
> reused after being aborted
> ------------------------------------------------------------------------------------------------------
>
>                 Key: HTTPASYNC-152
>                 URL: https://issues.apache.org/jira/browse/HTTPASYNC-152
>             Project: HttpComponents HttpAsyncClient
>          Issue Type: Bug
>    Affects Versions: 4.1.4
>            Reporter: Luca Cavanna
>            Assignee: Oleg Kalnichevski
>            Priority: Major
>             Fix For: 4.1.5
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> We are using http async client in the official Java REST client for 
> Elasticsearch. We recently introduced the ability to cancel requests. While 
> testing such new feature, I encountered a test failure that can be reproduced 
> when the same request instance is reused (although reset is called after each 
> run) after being cancelled. The following exception is raised, which calls 
> the reactor to shut down unexpectedly, which fails all subsequent requests:
> {noformat}
> Aug 15, 2019 2:04:52 PM 
> org.apache.http.impl.nio.client.InternalHttpAsyncClient run
> SEVERE: I/O reactor terminated abnormally
> org.apache.http.nio.reactor.IOReactorException: I/O dispatch worker 
> terminated abnormally
>       at 
> org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:359)
>       at 
> org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
>       at 
> org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
>       at java.base/java.lang.Thread.run(Thread.java:844)
> Caused by: java.lang.IllegalStateException: Connection must be created by 
> connection manager
>       at 
> org.apache.http.impl.nio.client.InternalIODispatch.createConnection(InternalIODispatch.java:56)
>       at 
> org.apache.http.impl.nio.client.InternalIODispatch.createConnection(InternalIODispatch.java:39)
>       at 
> org.apache.http.impl.nio.reactor.AbstractIODispatch.connected(AbstractIODispatch.java:70)
>       at 
> org.apache.http.impl.nio.reactor.BaseIOReactor.sessionCreated(BaseIOReactor.java:248)
>       at 
> org.apache.http.impl.nio.reactor.AbstractIOReactor.processNewChannels(AbstractIOReactor.java:427)
>       at 
> org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:287)
>       at 
> org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
>       at 
> org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
>       ... 1 more
> Exception in thread "main" java.util.concurrent.ExecutionException: 
> java.lang.IllegalStateException: I/O reactor has been shut down
>       at org.apache.http.concurrent.BasicFuture.getResult(BasicFuture.java:71)
>       at org.apache.http.concurrent.BasicFuture.get(BasicFuture.java:84)
>       at 
> org.apache.http.impl.nio.client.FutureWrapper.get(FutureWrapper.java:70)
>       at ClientTest.main(ClientTest.java:31)
> Caused by: java.lang.IllegalStateException: I/O reactor has been shut down
>       at org.apache.http.util.Asserts.check(Asserts.java:34)
>       at 
> org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.connect(DefaultConnectingIOReactor.java:228)
>       at 
> org.apache.http.nio.pool.AbstractNIOConnPool.processPendingRequest(AbstractNIOConnPool.java:481)
>       at 
> org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:280)
>       at 
> org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:295)
>       at 
> org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:377)
>       at 
> org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:129)
>       at 
> org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
>       at 
> org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:75)
>       at 
> org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:85)
>       at ClientTest.main(ClientTest.java:28)
> {noformat}
> The following snippet reproduces it most of the times:
> {code:java}
> import com.sun.net.httpserver.HttpServer;
> import org.apache.http.HttpHost;
> import org.apache.http.HttpResponse;
> import org.apache.http.client.methods.HttpGet;
> import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
> import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
> import java.net.InetAddress;
> import java.net.InetSocketAddress;
> import java.util.concurrent.CancellationException;
> import java.util.concurrent.Future;
> public class ClientTest {
>     public static void main(String[] args) throws Exception {
>         HttpServer httpServer = HttpServer.create(new 
> InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
>         httpServer.start();
>         httpServer.createContext("/test", exchange -> {
>             exchange.sendResponseHeaders(200, 0);
>             exchange.close();
>         });
>         HttpHost httpHost = new 
> HttpHost(httpServer.getAddress().getHostString(), 
> httpServer.getAddress().getPort());
>         try (CloseableHttpAsyncClient client = 
> HttpAsyncClientBuilder.create().build()) {
>             client.start();
>             HttpGet httpGet = new HttpGet("/test");
>             for (int i = 0; i < 10000; i++) {
>                 httpGet.reset();
>                 Future<HttpResponse> future = client.execute(httpHost, 
> httpGet, null);
>                 httpGet.abort();
>                 try {
>                     future.get();
>                     assert false;
>                 } catch(CancellationException e) {
>                     //expected
>                 }
>             }
>         } finally {
>             httpServer.stop(0);
>         }
>     }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to