Reputation: 829
I have this method:
private Mono<MyDTO[]> doRequest(List<Request> requests) {
return Flux.fromIterable(requests)
.map(Request::getParams)
.buffer(config.getBatchSize())
.map(params -> new HttpEntity<>(params, httpHeaders))
.flatMap(request ->
Mono.fromCallable(() -> {
log.info("Calling the service with a batch of {} requests...", request.getBody().size());
return plain.postForObject(config.getUrl(), request, MyDTO[].class);
})
.name("External Service")
.timeout(config.getTimeout()) -- Setting timeout of 10 seconds
.retryWhen(retrySpec)
)
.reduce(new MyDTO[]{}, ArrayUtils::addAll)
.onErrorMap(TimeoutException.class,
e -> new IllegalStateException(getRootCauseMessage(e))
)
.subscribeOn(boundedElastic()); // by default 10x detected CPU cores
I would expect that, if plain.postForObject
(plan is an instance of RestTemplate), takes more that 10s to respond, a TimeoutException.class
is thrown and therefore mapped to IllegalStateException.class
.
Actual Behavior
Timeout setting seems not be taken in consideration and the RestTemplate
goes into timeout due to the timeout set for the client (i.e. SocketTimeoutException
is thrown when reaching the 60s threshold):
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://anurl": Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:791)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:443)
at com.myproject.MyClient.lambda$doRequest$10(MyClient.java:127)
...
Steps to Reproduce I wrote this test but in fact I wasn't able to reproduce the issue, and the test passes:
when(plain.postForObject(anyString(), any(), any())).thenAnswer(
// simulate (infinite) blocking call
new AnswersWithDelay(1_000_000, invoke -> new OpenFIGIDTO[]{})
);
StepVerifier.create(client.doRequest(requests)
.verifyError(IllegalStateException.class);
Reactor version(s) used: 3.4.34 JVM version (java -version): 21-temurin
Is there anyone, with Reactor/Reactive knowledge, available to carefully explain me why it is not working as expected in real usage while the test is passing?
Thanks!
Upvotes: 0
Views: 33