重试 Mono 似乎会产生无限循环

Retry on Mono seems to generate an infinite loop

我正在尝试学习 Reactor 并创建了以下示例:

  fun dbThingErrorSometimes() : Mono<String> {
        return if (Random.nextBoolean()){
            processDbResult(pooledClient.execute("SELECT * FROM product"))
        }else{
            Mono.error(RuntimeException("boom"))
        }
    }

然后我在哪里使用它(在控制器中):

 @RequestMapping("/dbpooledretry")
    @ResponseBody
    fun dbExamplePoolRetrying(): Mono<String> {
        return dbService.dbThingErrorSometimes()
                .retry()
    }

当出现错误时,它会陷入无限循环(rest call 永远不会 returns 并且 cpu 会达到 100%)。为什么?

如文档所述Mono#retry

Re-subscribes to this Mono sequence if it signals any error, indefinitely.

所以这是预期的,它将在我们的余生中重试。

您的 retry() 方法只是重试 dbService.dbThingErrorSometimes() 返回的发布者,它可能是 Mono.error()dbService.dbThingErrorSometimes() 永远不会被重新调用,它发出的发布者只会被重新订阅。

因此,如果它 确实 发出错误,那么重新订阅同一个错误发布者永远不会改变结果,因此你的无限循环。

相反,您可能想让 Mono 变得懒惰,每次重试时重新调用 dbService.dbThingErrorSometimes() - 您可以通过将方法调用包装在 Mono.defer() 中来实现此目的。