reactor / reactor-addons

Additional optional modules for the Reactor project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

withVirtualTime does not affect Retry timeout

eximius313 opened this issue · comments

commented

Having this Mono:

public class MonoWithRetryTimeout {

    public static void main(String[] args) throws InterruptedException {
        createFailingRetry(1, 5, 10)
            .subscribe();

        Thread.sleep(100000);
    }

    public static Mono<String> createFailingRetry(final int minBackoff, final int maxBackoff, final int timeout){
        final Retry<Object> retry = Retry.anyOf(Exception.class)
                .exponentialBackoffWithJitter(Duration.ofSeconds(minBackoff), Duration.ofSeconds(maxBackoff))
                .timeout(Duration.ofSeconds(timeout));

        return Mono.<String>create(c -> c.error(new RuntimeException("Something went wrong")))
                .retryWhen(retry)
                .doOnError(e -> System.out.println("Error"))
                .subscribeOn(Schedulers.elastic());
    }
}

and we run the Main method, console output is as expected:

21:04:10.080 [main] DEBUG reactor.util.Loggers$LoggerFactory - Using Slf4j logging framework
21:04:10.266 [elastic-2] DEBUG reactor.retry.DefaultRetry - Scheduling retry attempt, retry context: iteration=1 exception=java.lang.RuntimeException: Something went wrong backoff={1389ms/5000ms}
21:04:11.662 [parallel-1] DEBUG reactor.retry.DefaultRetry - Scheduling retry attempt, retry context: iteration=2 exception=java.lang.RuntimeException: Something went wrong backoff={2159ms/5000ms}
21:04:13.822 [parallel-2] DEBUG reactor.retry.DefaultRetry - Scheduling retry attempt, retry context: iteration=3 exception=java.lang.RuntimeException: Something went wrong backoff={4987ms/5000ms}
21:04:18.811 [parallel-3] DEBUG reactor.retry.DefaultRetry - Retries exhausted, retry context: iteration=4 exception=java.lang.RuntimeException: Something went wrong backoff={EXHAUSTED}
Error

but when we run this test:

    @Test
    void shouldTimeoutRetry() {
        // given
        final int minBackoff = 1;
        final int maxBackoff = 2;
        final int timeout = 10;

        // then
        StepVerifier.withVirtualTime(() -> MonoWithRetryTimeout.createFailingRetry(minBackoff, maxBackoff, timeout))
            .expectSubscription()
            .expectNoEvent(Duration.ofSeconds(timeout))
            .thenAwait(Duration.ofSeconds(timeout))
            .expectError()
            .verify(Duration.ofSeconds(timeout));
    }

throws java.lang.AssertionError: VerifySubscriber timed out instead of passing

It is indeed a bug, the Retry function uses Instant.now() 😢

commented

Thank you!