我有一个 Spring Boot 应用程序,其中包含复杂的 react 流(它涉及 MongoDB 和 RabbitMQ 操作)。大多数时候它是有效的,但是......
某些方法返回 Mono<Void>
。这是一个典型的多层模式:
fun workflowStep(things: List<Thing>): Mono<Void> =
Flux.fromIterable(things).flatMap { thing -> doSomethingTo(thing) }.collectList().then()
比方说doSomethingTo()
返回 Mono<Void>
(它向数据库写入一些内容,发送消息等)。如果我只是将其替换为 Mono.empty()
那么一切都会按预期进行,但否则就不会。更具体地说,Mono 永远不会完成,它会运行所有处理,但会错过最后的终止信号。所以东西实际上是写入数据库的,消息实际上是发送的,等等。
为了证明缺乏终止是问题所在,这里有一个有效的技巧:
val hackedDelayedMono = Mono.empty<Void>().delayElement(Duration.ofSeconds(1))
return Mono.first(
workflowStep(things),
hackedDelayedMono
)
问题是,我该如何处理永远不会完成的 Mono,以弄清楚发生了什么?我没有地方可以放置日志语句或制动点,因为:
- 没有错误
- 没有发出任何信号
我如何检查 Mono 正在等待完成什么?
ps。我无法使用简单的 Mono 工作流程在应用程序之外重现此行为。
最佳答案
您可以通过在 react 流中使用 log()
运算符来跟踪和记录流中的事件。这对于更好地了解应用程序中发生的事件非常有用。
Flux.fromIterable(things)
.flatMap(thing -> doSomethingTo(thing))
.log()
.collectList()
.then()
Chained inside a sequence, it peeks at every event of the Flux or Mono upstream of it (including onNext, onError, and onComplete as well as subscriptions, cancellations, and requests).
Reactor Reference Documentation - Logging a Sequence
Reactor 引用文档还包含其他有关调试响应式(Reactive)流的有用建议,可以在此处找到:Debugging Reactor
关于spring-boot - 如何调试永远无法完成的 Mono,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65904851/