Spring WebFlux WebClient 挂起并且 Mono.timeout 没有捕捉到它
Spring WebFlux WebClient hangs and Mono.timeout doesn't catch it
我有相当简单的 Kotlin 代码,它总是阻塞并且从不阻塞 returns:
WebClient
.create()
.get()
.uri("https://httpbin.org/status/200")
.exchange()
.flatMap {
println("Status ${it.statusCode()}")
it.bodyToMono(String::class.java)
}
.timeout(Duration.ofSeconds(5), Mono.just("fallback"))
.map { println("Response $it") } // never runs
.block()
httpbin
在这种情况下 returns 没有内容(只有 headers),所以 bodyToMono
永远等待这里的内容?有没有可靠的方法来处理这种情况(阅读 Content-Length 不可靠)
我为 Mono.timeout 设置了后备值,为什么它不涵盖该值?
在这种情况下,httpbin.org 没有 return 响应主体,因此 bodyToMono
方法将 return 等同于 Mono.empty()
。
如果您将 map { println("Response $it") }
(永远不会 运行,因为我们没有得到正文)更改为 doOnSuccess { log.info("Response received") }
,则会打印 "Response received"
消息.
这意味着Mono
没有卡住,它只是用一个空体完成。
我也有同样的问题。看了Brain的回答,我觉得真正的问题还是解决不了。实际上我们需要在没有 body 的情况下对响应采取行动,例如用 Mono.just 回复(就像 Artem 在超时后想做的那样)。现在timeout()
无法处理这种情况,但doOnSuccess()
似乎也无法处理这种情况,因为它会因具有body 或没有body 而被调用。在 doOnSuccess()
中我们仍然无法知道 clientReponse 是否有 body 然后采取不同的行动。
正如 Brian 之前所说,doOn** 有 side-effects 仅用于日志使用。
我有相当简单的 Kotlin 代码,它总是阻塞并且从不阻塞 returns:
WebClient
.create()
.get()
.uri("https://httpbin.org/status/200")
.exchange()
.flatMap {
println("Status ${it.statusCode()}")
it.bodyToMono(String::class.java)
}
.timeout(Duration.ofSeconds(5), Mono.just("fallback"))
.map { println("Response $it") } // never runs
.block()
httpbin
在这种情况下 returns 没有内容(只有 headers),所以bodyToMono
永远等待这里的内容?有没有可靠的方法来处理这种情况(阅读 Content-Length 不可靠)我为 Mono.timeout 设置了后备值,为什么它不涵盖该值?
在这种情况下,httpbin.org 没有 return 响应主体,因此 bodyToMono
方法将 return 等同于 Mono.empty()
。
如果您将 map { println("Response $it") }
(永远不会 运行,因为我们没有得到正文)更改为 doOnSuccess { log.info("Response received") }
,则会打印 "Response received"
消息.
这意味着Mono
没有卡住,它只是用一个空体完成。
我也有同样的问题。看了Brain的回答,我觉得真正的问题还是解决不了。实际上我们需要在没有 body 的情况下对响应采取行动,例如用 Mono.just 回复(就像 Artem 在超时后想做的那样)。现在timeout()
无法处理这种情况,但doOnSuccess()
似乎也无法处理这种情况,因为它会因具有body 或没有body 而被调用。在 doOnSuccess()
中我们仍然无法知道 clientReponse 是否有 body 然后采取不同的行动。
正如 Brian 之前所说,doOn** 有 side-effects 仅用于日志使用。