出错时再调用一次并在 webflux 中重试
on error do another call and retry in webflux
我想使用来自 spring webflux 的 WebClient
执行以下操作:
- 致电
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
但我不太确定如何使用它。
我完成这项工作的唯一方法是使用 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);
}
}));
我想使用来自 spring webflux 的 WebClient
执行以下操作:
- 致电
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
但我不太确定如何使用它。
我完成这项工作的唯一方法是使用 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);
}
}));