为了账号安全,请及时绑定邮箱和手机立即绑定

出错时再次调用并在 webflux 中重试

出错时再次调用并在 webflux 中重试

梦里花落0921 2022-11-02 10:44:12
我想使用WebClientfrom spring webflux 执行以下操作:称呼endpoint1如果它失败并出现预期错误,那么打电话endpoint2和只重试endpoint1一次我已经做到了这一点:webclient.get()  .uri("/endpoint1")  .retrieve()  .bodyToFlux(MyBody.class)  .retry(error -> {     if (error == expectedError) {       webclient.get()         .uri("/endpoint2")         .retrieve().block();       return true;     } else {       false;     });请求时我无法阻止,endpoint2因为我会收到以下错误:(block()/blockFirst()/blockLast() are blocking, which is not supported in thread我也不想阻止)。也许我应该使用retryWhen,但我不确定如何使用它。
查看完整描述

1 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

我完成这项工作的唯一方法是retryWhen我无法使用reactor.retry.Retry#doOnRetry,因为它只接受 aConsumer而不是 a Monoor Fluxor Publisher。


片段如下:


webclient.get()

  .uri("/endpoint1")

  .retrieve()

  .bodyToFlux(MyBody.class)

  .retryWhen(errorCurrentAttempt -> errorCurrentAttempt

                .flatMap(currentError -> Mono.subscriberContext().map(ctx -> Tuples.of(currentError, ctx)))

                .flatMap(tp -> {

                    Context ctx = tp.getT2();

                    Throwable error = tp.getT1();

                    int maxAttempts = 3;

                    Integer rl = ctx.getOrDefault("retriesLeft", maxAttempts);

                    if (rl != null && rl > 0 && error == myExpectedError) {

                        // Call endpoint and retry

                        return webclient.get()

                                .uri("/endpoint2")

                                .retrieve()

                                .thenReturn(ctx.put("retriesLeft", rl - 1));

                    } else {

                        // Finish retries

                        return Mono.<Object>error(error);

                    }

                }));


查看完整回答
反对 回复 2022-11-02
  • 1 回答
  • 0 关注
  • 196 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信