I have a problem where a application keeps blocking indefinitely on a post call made with a RestTemplate
from Spring Boot.
ResponseEntity<String> response = restTemplate.postForEntity(destination.getUri(), request, String.class);
We use the default standard JDK implementation and create it like this:
this.restTemplate = restTemplateBuilder
.setConnectTimeout(5000)
.setReadTimeout(5000)
.build();
Which sets the connection and read timeout to 5 seconds. But it seems this is not an absolute value, as soon as our application receives some bytes this read timeout resets and this causes our application to wait indefinitely.
I rather have an absolute read timeout where if you don't get the end response in less than 5 seconds the template throws an TimeoutException
.
I couldn't find something like this in the options for the default client?
---EDIT---
I tried out @Peekay answer but it doesn't seem to work:
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionTimeToLive(1, TimeUnit.SECONDS)
.setConnectionManager(new PoolingHttpClientConnectionManager())
.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setHttpClient(httpClient);
return new RestTemplate(clientHttpRequestFactory);
I have also tried different implementations of the client's RestTemplate
e.g. HttpComponentsClientHttp
, Netty4Client
and OkHttp3Client
created them like so:
Netty4ClientHttpRequestFactory factory = new Netty4ClientHttpRequestFactory();
factory.setConnectTimeout(timeout);
factory.setReadTimeout(readTimeout);
return new RestTemplate(factory);
And tested them on a response that took longer than 5 seconds to respond. All of them except for Netty, which returned a ReadTimeoutException
, had returned a 200 success. Unfortunately I cannot switch to that client, it seems you need to implement it yourself if you want to keep using the default client.