重试 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()
中来实现此目的。
我正在尝试学习 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()
中来实现此目的。