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

got*_*ch4 2 project-reactor spring-webflux

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

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

然后我在使用它的地方(在控制器中):

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

当它出现错误时,它会陷入无限循环(其余调用永远不会返回,CPU 达到 100%)。为什么?

Mic*_*rry 5

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

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

相反,您可能希望在每次重试时进行Mono懒惰的重新调用dbService.dbThingErrorSometimes()- 您可以通过将该方法调用包装在Mono.defer().