Conditional repeat or retry on Mono with webclient from Spring WebFlux

前端 未结 1 1432
野趣味
野趣味 2021-02-02 16:02

What i want to do is a conditional repeat on a Mono in Webflux with webclient.The Situation is the following:

We have some business rest service service that returns a g

相关标签:
1条回答
  • 2021-02-02 16:59

    Yes, it is possible.

    Mono has two concepts for re-subscribing (and thus, re-triggering the request)

    • retry = re-subscribe if the upstream completed with an exception
    • repeat = re-subscribe if the upstream completed successfully

    Each concept has multiple overloaded methods on Mono for different use cases. Look for the retry* and repeat* methods. For example, to retry a maximum number of times with no delay, use retry(int numRetries).

    More complex use cases are supported via the retryWhen and repeatWhen methods, as shown in the following examples.

    retryWhen

    To retry if the mono completed with an exception a maximum of 5 times with 5 seconds between each attempt:

    // From reactor-core >= v3.3.4.RELEASE
    import reactor.util.retry.Retry;
    
    this.webClient
            .post()
            .uri(SERVICE_URL)
            .body(BodyInserters.fromValue(docRequest))
            .retrieve()
            .bodyToMono(Document.class)
            .retryWhen(Retry.fixedDelay(5, Duration.ofSeconds(5)))
            .delaySubscription(Duration.ofSeconds(10))
    
    

    The retry builder supports other backoff strategies (e.g. exponential) and other options to fully customize retries.

    Note the retryWhen(Retry) method used above was added in reactor-core v3.3.4.RELEASE, and the retryWhen(Function) method was deprecated. Prior to reactor-core v3.3.4.RELEASE, you could use the retry function builder from reactor-extras project to create a Function to pass to retryWhen(Function).

    repeatWhen

    If you need to repeat on success, then use .repeatWhen or .repeatWhenEmpty instead of .retryWhen above.

    Use the repeat function builder from reactor-extras project to create the repeat Function as follows:

    // From reactor-extras
    import reactor.retry.Repeat;
    
    this.webClient
            .post()
            .uri(SERVICE_URL)
            .body(BodyInserters.fromValue(docRequest))
            .retrieve()
            .bodyToMono(Document.class)
            .filter(document -> !document.isEmpty())
            .repeatWhenEmpty(Repeat.onlyIf(repeatContext -> true)
                    .exponentialBackoff(Duration.ofSeconds(5), Duration.ofSeconds(10))
                    .timeout(Duration.ofSeconds(30)))
            .delaySubscription(Duration.ofSeconds(10))
    

    You can also chain a .retry* with a .repeat* if you want to re-subscribe on both success or failure.

    0 讨论(0)
提交回复
热议问题