Description
Motivation
There are cases where the coroutine dispatcher is changed when performing blocking processing.
@GetMapping("/sample")
suspend fun sample(): String {
// do non-blocking call
withContext(blockingDispatcher) {
// do blocking call
}
// do non-blocking call
...
}
But now WebFlux uses Unconfined dispatcher.
https://github.com/spring-projects/spring-framework/blob/5.3.x/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java#L74
So once we change the dispatcher, subsequent processing will also be executed by that dispatcher.
For example, in the following example, it will be executed by blockingExecutor thread even after withContext.
@GetMapping("/test/hello1")
suspend fun hello1(): String {
// reactor-http-nio-N thread
log.info("thread={}", Thread.currentThread().name)
withContext(blockingDispatcher) {
// blockingExecutor-N thread
log.info("thread={}", Thread.currentThread().name)
// do blocking call
}
// blockingExecutor-N thread
log.info("thread={}", Thread.currentThread().name)
return "hello"
}
We can work around this issue by using the default dispatcher instead of the Unconfined dispatcher.
@GetMapping("/test/hello2")
suspend fun hello2(): String {
return withContext(Dispatchers.Default) {
// DefaultDispatcher-worker-N thread
log.info("thread={}", Thread.currentThread().name)
withContext(blockingDispatcher) {
// blockingExecutor-N thread
log.info("thread={}", Thread.currentThread().name)
// do blocking call
}
// DefaultDispatcher-worker-N thread
log.info("thread={}", Thread.currentThread().name)
"hello"
}
}
However, writing withContext(Dispatchers.Default)
on all controller methods can be tedious.
So I want to be able to change the coroutine dispatcher used by WebFlux.
How
How about making it possible to change by registering a class such as CoroutinesDispatchersProvider in the bean?
interface CoroutinesDispatchersProvider {
fun provide(request: ServerHttpRequest): CoroutineDispatcher
}
For example, a framework called armeria allows we to specify a dispatcher
https://armeria.dev/docs/server-annotated-service#coroutine-dispatcher