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: