Problem
Using HttpClient from Java 11 (JDK, not Apache), how can I retry requests?
Lets say I want to retry a request up to 10 times if it did not return a status code of 200 or threw an exception.
Attempt
Currently I am composing the returned future with re-schedules in a loop and I am wondering whether there might be a better or more elegant way.
CompletableFuture<HttpResponse<Foo>> task = client.sendAsync(request, bodyHandler);
for (int i = 0; i < 10; i++) {
task = task.thenComposeAsync(response -> response.statusCode() == 200 ?
CompletableFuture.completedFuture(response) :
client.sendAsync(request, bodyHandler));
}
// Do something with 'task' ...
And if we add retries for exceptional cases as well, I end up with
CompletableFuture<HttpResponse<Foo>> task = client.sendAsync(request, bodyHandler);
for (int i = 0; i < 10; i++) {
task = task.thenComposeAsync(response ->
response.statusCode() == 200 ?
CompletableFuture.completedFuture(response) :
client.sendAsync(request, bodyHandler))
.exceptionallyComposeAsync(e ->
client.sendAsync(request, bodyHandler));
}
// Do something with 'task' ...
Unfortunately there does not seem to be any composeAsync that triggers for both, regular completion and exceptional. There is handleAsync but it does not compose, the lambda is required to return U and not CompletionStage<U> there.
Other frameworks
For the sake of QA, I am also interested in answers that show how to achieve this with other frameworks, but I wont accept them.
For example, I have seen a library called Failsafe which might offer an elegant solution to this (see jodah.net/failsafe).
Reference
For reference, here are some related JavaDoc links: