package org.javacodegeeks.examples.v3.retry;

import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
import reactor.util.retry.Retry;
import reactor.util.retry.RetryBackoffSpec;

import java.time.Duration;

import static java.time.LocalDateTime.now;

public class RetryWhenMain {

    public static final RetryBackoffSpec RETRY_SPEC =
        Retry.backoff(3, Duration.ofSeconds(2))
            .doBeforeRetry(retrySignal -> System.out.printf("[%s][%s] Error, before retry\n", now(), Thread.currentThread().getName()))
            .doAfterRetry(retrySignal -> System.out.printf("[%s][%s] Error, after retry\n", now(), Thread.currentThread().getName()))
            .scheduler(Schedulers.boundedElastic())
            .transientErrors(false);

    public static void main(String[] args) {
        Flux.just(1, 2, 3, 4, 5, 6)
            .doOnNext(i -> {
                if (i != 3) {
                    System.out.printf("[%s][%s] Got %s\n", now(), Thread.currentThread().getName(), i);
                } else {
                    System.out.printf("[%s][%s] Got illegal %s\n", now(), Thread.currentThread().getName(), i);
                    throw new IllegalStateException("Got illegal 3");
                }
            })
            .retryWhen(RETRY_SPEC)
            .subscribeOn(Schedulers.parallel())
            .blockLast();
    }
}
