How to retry a failed call to a Webflux.outboundgateway in Spring integration
Asked Answered
T

1

2

I have a spring integration flow defined in the flow DSL syntax. One of my handlers is a Webflux.outboundGateway. When the remote URI is not accessible, an exception is thrown and sent to the "errorChannel". I'm trying to have the flow to retry, but so far with no success (the call is never retried). Here is what my configuration looks like:

@Bean
public IntegrationFlow retriableFlow() {
    return IntegrationFlows
            .from(...)
            .handle(
                    WebFlux.outboundGateway(m ->
                        UriComponentsBuilder.fromUriString(remoteGateway + "/foo/bar")
                                            .build()
                                            .toUri(), webClient)
                    .httpMethod(HttpMethod.POST)
                    .expectedResponseType(String.class)
                    .replyPayloadToFlux(true), e -> e.advice(retryAdvice())
            )
            // [ ... ]
            .get();
}
@Bean
public Advice retryAdvice() {
   RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
   RetryTemplate retryTemplate = new RetryTemplate();
   ExponentialBackOffPolicy retryPolicy = new ExponentialBackOffPolicy();
   retryPolicy.setInitialInterval(1000);
   retryPolicy.setMaxInterval(20000);
   retryTemplate.setBackOffPolicy(retryPolicy);
   advice.setRetryTemplate(retryTemplate);
   return advice;
}

Should I be using something different than the RequestHandlerRetryAdvice? If so, what should it be?

Tiffany answered 21/6, 2018 at 14:54 Comment(0)
S
2

Webflux is, by definition, async, which means the Mono (reply) is satisfied asynchronously when the request completes/fails, not on the calling thread. Hence the advice won't help because the "send" part of the request is always successful.

You would have to perform retries via a flow on the error channel (assigned somewhere near the start of the flow). With, perhaps, some header indicating how many times you have retried.

The ErrorMessage has properties failedMessage and cause; you can resend the failedMessage.

You could turn off async so the calling thread blocks, but that really defeats the whole purpose of using WebFlux.

Stroman answered 21/6, 2018 at 15:40 Comment(3)
Hi Gary, I have a follow-up question: I'm trying to achieve the same as OP, with the difference that I have an Ftp.outboundGateway() on which I'm performing an AbstractRemoteFileOutboundGateway.Command.GET. I too have the problem that my retry advice is never executed on an error. I haven't quite understood your remark about the reply being satisfied asynchronously, but is it possible that here the advice is never executed, too? According to the following question, I would expect it to work: #31254722Crumpler
You should not comment on an answered question with a new question. Yes, the advice will be invoked if properly configured; the FTP gateway is synchronous so doesn't have the async problem. Ask a new question, showing your configuration. Answers will be sporadic this week because we are the SpringOne Platform conference.Stroman
Thanks Gary, I posted a new question here.Crumpler

© 2022 - 2024 — McMap. All rights reserved.