diff --git a/spring/webflux/Reactor.md b/spring/webflux/Reactor.md index 1e5d89e..a3c20d3 100644 --- a/spring/webflux/Reactor.md +++ b/spring/webflux/Reactor.md @@ -58,6 +58,9 @@ - [Using resources and the finally block](#using-resources-and-the-finally-block) - [doFinally](#dofinally) - [using](#using) + - [retry](#retry) + - [retry原理](#retry原理) + - [retryWhen](#retrywhen) # Reactor ## Reactive Programming @@ -909,6 +912,54 @@ Flux.using( - `Disposable::dispose`: resource cleanup +#### retry +`retry`允许对产生错误的sequence进行重试。 + +```java +Flux.interval(Duration.ofMillis(250)) + .map(input -> { + if (input < 3) return "tick " + input; + throw new RuntimeException("boom"); + }) + .retry(1) + .elapsed() + .subscribe(System.out::println, System.err::println); + +Thread.sleep(2100); +``` +在上述示例中,`retry(1)`会对错误执行一次重试(`upstream重新开始生成`)。其产生结果如下所示: +```java +259,tick 0 +249,tick 1 +251,tick 2 +506,tick 0 +248,tick 1 +253,tick 2 +java.lang.RuntimeException: boom +``` + +##### retry原理 +下游在上游调用`onError`时,会判断重试次数是否为0,如果不为0,会对重试次数进行减1,并且重新对上游调用`subscribe`,这会令上游`重新从头开始生成序列`。 + +直到重试次数为0之后,`FluxRetry`才会将onError传递给下游。 + +#### retryWhen +`retryWhen`会使用`companion flux`来判断错误时是否应该回滚。`companion flux`由operator创建,但是用户会通过装饰`companion flux`来自定义重试条件。 + +`companion flux`是一个`Flux`类型的值,该值将会被传递给`Retry`方法/策略(`retryWhen`只接受一个`Retry`类型的参数)。 + +使用者可以对`retry方法`进行指定,`retry方法`会返回一个`Publisher`类型的值。 + +> Retry是一个抽象类,但是提供了`Retry#from`方法,通过该方法可以将lambda转换为Retry对象。 + +Retry周期如下所示: +- 每当error发生时,都会将`RetrySignal`发送到companion flux中,此时`companion flux`已经被`retry方法`装饰过了 + - `Flux`将会包含至今所有的重试尝试信息,并且可以通过其访问error和error关联的元数据 +- 如果`companion flux`发送了一个值,那么会触发重试 +- 如果`companion flux`complete,将会对error执行swallow操作,retry cycle将会停止,并且也会导致sequence complete +- 如果`companion flux`产生了一个error,retry cycle将会终止,并且导致sequence按异常终止 + +