в случае ошибки сделайте еще один вызов и повторите попытку в webflux - PullRequest
0 голосов
/ 30 апреля 2019

Я бы хотел сделать следующее, используя WebClient из весеннего 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 Ответ

1 голос
/ 01 мая 2019

Единственный способ, которым я сделал эту работу, был с retryWhen, я не мог использовать reactor.retry.Retry#doOnRetry, потому что он принимает только Consumer, а не Mono или Flux или 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);
                    }
                }));
...