[
https://issues.apache.org/jira/browse/HTTPASYNC-152?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16965419#comment-16965419
]
Anurag Agarwal commented on HTTPASYNC-152:
------------------------------------------
I may have found a second speculation, which may be our case in production do
verify if that can be the case as I am not the best in dealing with threads and
concurrency. The situation is as follows:
# At the same time both sessionRequest.completed and sessionRequest.cancel is
executed from two different threads.
# sessionRequest is marked as completed by the cancel call.
# sessionRequest from completed thus returns because the request has already
been marked as completed.
# Now since setting termination to true in cancel call is not within block
statements, before it is set to true the check is made if the request is
terminated to proceed further to sessionCreated(key, session) call.
# Rest of the call for cancel proceeds as is, but since the current session
doesn't have an attached connection with it, sessionCreated(key, session) call
will fail with the above error.
> "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
>
>
> 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]