I'm trying to understand the difference between the various timeout configurations in HttpClient and the simplest way to configure it.
The various options are shown in this code:
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(connectionRequestTimeout, TimeUnit.MILLISECONDS)
.setResponseTimeout(responseTimeout, TimeUnit.MILLISECONDS)
.setConnectTimeout(connectTimeout, TimeUnit.MILLISECONDS) // Deprecated - Use {@link ConnectionConfig.Builder#setConnectTimeout(Timeout)}.
.build();
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setConnectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
.setSocketTimeout(socketTimeout, TimeUnit.MILLISECONDS)
.build();
SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout(socketTimeout, TimeUnit.MILLISECONDS)
.build();
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setDefaultConnectionConfig(connectionConfig)
.setDefaultSocketConfig(socketConfig)
.build();
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
My current understanding is this:
ConnectionRequestTimeout is the time taken to get a connection from the pool - relevant if under load.
ConnectTimeout is the time taken to establish the connection.
But what is the difference between:
RequestConfig.setResponseTimeout()
ConnectionConfig.setSocketTimeout()
SocketConfig.setSoTimeout()
they all seem to be read / response timeouts for a request. Do I only need to set one of these?
From some limited testing it seems ResponseTimeout overrides the others possibly implying thats all I need.
In this case it would be nice just to have to use RequestConfig to set all three but the ConnectTimeout has been deprecated there and moved to ConnectionConfig which also contains the SocketTimeout.
I'm using this with SpringBoot 3 / Spring 6 and the recent removal of the readTimeout configuration option on HttpComponentsClientHttpRequestFactory seems to imply its best to set this up directly on the HttpClient.
In your case, setting just ResponseTimeout in RequestConfig will typically cover your needs for managing how long a request waits for a response, making it easier to configure and understand. Here’s a suggested approach to simplify things:
Here’s a simplified configuration:
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(connectionRequestTimeout, TimeUnit.MILLISECONDS)
.setResponseTimeout(responseTimeout, TimeUnit.MILLISECONDS)
.build();
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setConnectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
.build();
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setDefaultConnectionConfig(connectionConfig)
.build();
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
This approach keeps the configuration centralized and manageable, leveraging ResponseTimeout as your primary timeout, while ensuring ConnectTimeout is properly configured in ConnectionConfig. This setup should work well with Spring Boot 3 / Spring 6, aligning with recent updates in timeout handling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With