javahttptimeoutapache-httpclient-4.xapache-httpasyncclient

difference between timeout settings on RequestConfig and IOReactorConfig?


I am using Apache HTTP async client and I have to some configurations about it.

I have the following code, but I am confused when setting RequestConfig and IOReactorConfig because you can specify the timeouts configs for both of them.

My Question is: what are the difference of the timeouts between two of these configs? Is it double work and I can just set on one of the Config? Or, the timeouts of these two Configs are controlling different things?

    RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(socketTimeout)
            .setConnectTimeout(connectionTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout)
            .build();

    // Create I/O reactor configuration
    IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
            .setIoThreadCount(Runtime.getRuntime().availableProcessors())
            .setConnectTimeout(connectionTimeout)
            .setSoTimeout(socketTimeout)
            .build();

    // Create a custom I/O reactort
    ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);

    PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
    cm.setMaxTotal(maxConnTotal);
    cm.setDefaultMaxPerRoute(maxConnPerRoute);

    HttpAsyncClientBuilder defaultBuilder = HttpAsyncClients.custom()
            .setDefaultRequestConfig(requestConfig)
            .setConnectionManager(cm)
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .setRedirectStrategy(new LaxRedirectStrategy());

Solution

  • I/O reactor parameters apply to connection channels managed by an I/O reactor. Connection channels represent bi-directional streams of data and are application protocol agnostic.

    HTTP request parameters apply to individual HTTP requests and control the way those requests get executed.

    Some long time ago users asked for an easy way to override socket timeout on a per request basis. In the retrospect the decision to introduce such parameter was likely a mistake.

    Important distinction between the socket timeout on the connection channel level and that on the HTTP level is the latter applies only after an HTTP route has been fully established, the process which may involve an TLS upgrade and intermediate proxy tunnel hops, whereas connection channel level timeout applies to all I/O on that channel immediately.

    Think of IOReactorConfig as a default and RequestConfig as a case by case override.

    RequestConfig#socketTimeout has been removed in HttpClient 5.0