Reactive programming can be used to solve a lot of different use cases. For
instance, reactive programming can be really helpful for cases where timing is an issue. An example of such a case
Let’s have a look at some different implementations using Project Reactor
(https://projectreactor.io) for Java. The
Using Reactor to retry with exponentional backoff
In the next
private Mono callAPI() { return Mono.defer(() -> { System.out.println("API call "); return api.monoWithException(); }); }
In our first attempt we use the reactor operator retryWhen. This operator can be used to resubscribe to the publisher in case of an exception. As a parameter it takes a function that allows us to

Figure 1: retryWhen
callAPI() .retryWhen(errors -> errors .zipWith(Flux.range(1, 4), (n, i) -> i) .flatMap(error -> Mono.delay(ofMillis(10))));
We combine each error with
zipWith(error1,1).flatMap(delay) // resubscribes after 10ms zipWith(error2,2).flatMap(delay) // resubscribes after 10ms zipWith(error3,3).flatMap(delay) // resubscribes after 10ms zipWith(error4,4).flatMap(delay) // completes
After the first try and 4 retries, the producer completes when the
callAPI() .retryWhen(errors -> errors .zipWith(Flux.range(1, 4), (n, i) -> i) .flatMap(error -> Mono.delay(ofMillis((int) Math.pow(10, error)))));
The downside of this approach is that after the retries are done and the
Existing retry logic in reactor and reactor-extras
The reactor core library has a
callAPI().retryBackoff(5, ofMillis(10), ofMillis(1000))
For our final
callAPI().retryWhen(any().exponentialBackoff(ofMillis(10), ofMillis(1000)).retryMax(5))
In case there are still errors after we are done retrying, a RetryExhaustedException is thrown. As an alternative to the exponentionalBackoff, reactor-extra also allows us to create a scheduled retry with withBackoffScheduler, a
Conclusion
Project Reactor has several expressive solutions to construct retry logic. This allows us to have great control over how and when we retry certain pieces of logic without having to write much code. When you don’t want to use an extra library, the core reactor library can be used to create a
More information from Trifork:


Nice! Thanks
[…] Например, что будет, если внешний API ответит 500 ошибкой? В нашем случае мы можем воспользоваться стандартным механизмом Reactor .retryBackoff() — он попробует отправить сообщение ещё несколько раз, увеличивая задержку между повторными сообщениями. Можно также настроить стрим на отлавливание определённых ошибок и реагировать только на них. Подробнее можно посмотреть тут. […]