You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Daniel Krawczyk (JIRA)" <ji...@apache.org> on 2017/05/05 09:37:04 UTC

[jira] [Created] (HTTPASYNC-121) Async client does not respect IOReactor's connection timeout setting

Daniel Krawczyk created HTTPASYNC-121:
-----------------------------------------

             Summary: Async client does not respect IOReactor's connection timeout setting
                 Key: HTTPASYNC-121
                 URL: https://issues.apache.org/jira/browse/HTTPASYNC-121
             Project: HttpComponents HttpAsyncClient
          Issue Type: Bug
    Affects Versions: 4.1.3
            Reporter: Daniel Krawczyk


Hello, I've noticed an issue with the async client where connection timeout setting is not respected when configured for `IOReactor` object. 

When I create the client like this:
{code}
CloseableHttpAsyncClient createAsyncClient() {
     return HttpAsyncClientBuilder.create()
                .setConnectionManager(connectionManager())
                .build();
}
{code}

where connection manager is configured as follows:
{code}
private PoolingNHttpClientConnectionManager connectionManager() {
            IOReactorConfig reactorConfig = IOReactorConfig.custom()
                    .setConnectTimeout(config.getConnectionTimeout()) // this doesn't work
                    .setSoTimeout(config.getSocketTimeout()) // this works
                    .setSelectInterval(config.getTimeoutCheckInterval())
                    .setIoThreadCount(config.getNioThreads())
                    .setTcpNoDelay(true)
                    .build();
            ConnectingIOReactor reactor = new DefaultConnectingIOReactor(reactorConfig, threadFactory());
            return new PoolingNHttpClientConnectionManager(reactor);
    }
{code} 
the `setConnectTimeout(...)` option is not respected.

After some longer time (this might be some system default? - 30 or 120 seconds, depends on the system I run the code) I get an exception thrown from a native method:
{code}
11:27:02.223 [pool-2-thread-1] DEBUG org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager - Connection request failed
java.net.ConnectException: Operation timed out
	at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
	at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:716)
	at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvent(DefaultConnectingIOReactor.java:171)
	at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvents(DefaultConnectingIOReactor.java:145)
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:348)
	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:194)
	at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
	at java.lang.Thread.run(Thread.java:745)
{code}

On the other hand the socket timeout setting works as expected.

... 

After debugging this, I found a way to cope with that by adding a default request config on the client:
{code}
CloseableHttpAsyncClient createAsyncClient() {
     return HttpAsyncClientBuilder.create()
                .setConnectionManager(connectionManager())
                .setDefaultRequestConfig(requestConfig()) // this works
                .build();
}
private RequestConfig requestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(config.getConnectionTimeout()) // this works
                .setSocketTimeout(config.getSocketTimeout()) // this works as well
                .build();
}
{code}

This way it works, I get an exception after specified time:
{code}
11:05:37.267 [pool-2-thread-1] DEBUG org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager - Connection request failed
java.net.ConnectException: null
	at org.apache.http.nio.pool.RouteSpecificPool.timeout(RouteSpecificPool.java:168)
	at org.apache.http.nio.pool.AbstractNIOConnPool.requestTimeout(AbstractNIOConnPool.java:584)
	at org.apache.http.nio.pool.AbstractNIOConnPool$InternalSessionRequestCallback.timeout(AbstractNIOConnPool.java:851)
	at org.apache.http.impl.nio.reactor.SessionRequestImpl.timeout(SessionRequestImpl.java:183)
	at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processTimeouts(DefaultConnectingIOReactor.java:210)
	at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvents(DefaultConnectingIOReactor.java:155)
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:348)
	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:194)
	at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
	at java.lang.Thread.run(Thread.java:745)
{code}

The test I performed looked something like this (groovy/spock):
{code}
    def "test bare client"() {
        given:
        def client = asyncClientFactory.createAsyncClient() // creates client with some short connection timeout
        client.start()

        when:
        HttpGet request = new HttpGet("http://10.0.0.0") // call some non-routable IP to trigger the connection timeout
        def response = client.execute(request, null).get()

        then:
        def e = thrown(ExecutionException)
        e.cause instanceof ConnectException

        cleanup:
        client.close()
}
{code}

Regards,
Daniel



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org