Ber*_*ado 4 java spring webclient project-reactor spring-webflux
我想做的是在带有webclient的Webflux中的Mono上有条件地重复。情况如下:
我们有一些商务休息服务服务,可返回生成的文档。此文档的生成是由在此之前调用的另一服务触发的。但是,回到正题:文档生成服务需要10到30秒。我们要做的是:10秒钟后检查是否生成文档(单声道)。如果是这样,一切都很好。如果不是,请在5秒钟后重复(或重试)并检查是否生成了文档。依此类推,直到(最坏的情况)在30秒后超时。这可能吗?一些(伪)代码:
return this.webClient.post().uri(SERVICE_URL)).
body(BodyInserters.fromObject(docRequest)).retrieve().
bodyToMono(Document.class).
delaySubscription(Duration.ofSeconds(10)).
repeat5TimesWithDynamicTimeDelayUntil(!document.isEmpty()).
subscribe();
Run Code Online (Sandbox Code Playgroud)
格蕾兹·伯纳多
对的,这是可能的。
Mono 有两个用于重新订阅(因此,重新触发请求)的概念
每个概念都有Mono针对不同用例的多种重载方法。寻找retry*和repeat*方法。例如,一个常见的用例是通过尝试使用指数补偿策略retryBackoff。
通过retryWhen和支持更复杂的用例repeatWhen。该反应器的额外项目包括一些建筑商,以帮助您构建功能传递给这些方法。
这是一个示例,该示例重试单声道是否完成(异常除外)最多5次,每次尝试之间间隔5秒
this.webClient
.post()
.uri(SERVICE_URL)
.body(BodyInserters.fromObject(docRequest))
.retrieve()
.bodyToMono(Document.class)
.retryWhen(Retry.any()
.fixedBackoff(Duration.ofSeconds(5))
.retryMax(5))
.delaySubscription(Duration.ofSeconds(10))
Run Code Online (Sandbox Code Playgroud)
还有其他退避策略(例如指数)和其他选项可用于完全自定义重试(例如,使用超时而不是最大重试次数)。
如果您需要成功重复一次,请使用.repeatWhen(Repeat...)或.repeatWhenEmpty(Repeat...)代替.retryWhen(Retry...)上面的内容。例如:
this.webClient
.post()
.uri(SERVICE_URL)
.body(BodyInserters.fromObject(docRequest))
.retrieve()
.bodyToMono(Document.class)
.filter(document -> !document.isEmpty())
.repeatWhenEmpty(Repeat.onlyIf(repeatContext -> true)
.exponentialBackoff(Duration.ofSeconds(5), Duration.ofSeconds(10))
.timeout(Duration.ofSeconds(30)))
.delaySubscription(Duration.ofSeconds(10))
Run Code Online (Sandbox Code Playgroud)
如果要重新订阅成功或失败,也可以将a .retry*与a 链接在一起.repeat*。
| 归档时间: |
|
| 查看次数: |
2183 次 |
| 最近记录: |