I have a simple controller as below in my spring-webflux application,
@GetMapping("/ping")
suspend fun ping(): ResponseEntity<Map<String, Boolean>> {
println(coroutineContext)
waitforIO()
return ResponseEntity(mapOf("success" to true), HttpStatus.OK)
}
suspend fun waitforIO() {
println(coroutineContext)
delay(1000)
}
The output looks like
[Context1{micrometer.observation={name=http.server.requests(null), error=null, context=name='http.server.requests', contextualName='null', error='null', lowCardinalityKeyValues=[exception='none', method='GET', outcome='SUCCESS', status='200', uri='UNKNOWN'], highCardinalityKeyValues=[http.url='/ping'], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=0.066692583, duration(nanos)=6.6692583E7, startTimeNanos=475384383429625}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@4b6502a5'], parentObservation=null}}, MonoCoroutine{Active}@33bfeb7d, Dispatchers.Unconfined]
[Context1{micrometer.observation={name=http.server.requests(null), error=null, context=name='http.server.requests', contextualName='null', error='null', lowCardinalityKeyValues=[exception='none', method='GET', outcome='SUCCESS', status='200', uri='UNKNOWN'], highCardinalityKeyValues=[http.url='/ping'], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=0.068251166, duration(nanos)=6.8251166E7, startTimeNanos=475384383429625}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@4b6502a5'], parentObservation=null}}, MonoCoroutine{Active}@33bfeb7d, Dispatchers.Unconfined]
Can someone elaborate me why this is using Dispatchers.Unconfined instead of Dispatchers.Default? AFAIK, Default should be picked by Default (obvious!).
I am using the below configurations if that would play some role in debugging this,
OpenJDK Runtime Environment JBR-17.0.7+7-985.2-nomod (build 17.0.7+7-b985.2) kotlin("jvm") version "1.8.22" kotlin("plugin.spring") version "1.8.22" id("org.springframework.boot") version "3.1.5" id("io.spring.dependency-management") version "1.1.3" springCloudVersion="2022.0.4" All dependencies are managed by spring-cloud-dependencies - 2022.0.4.
Have asked this question 2 days back on SO (https://stackoverflow.com/questions/77810077/controller-code-using-unconfined-dispatcher-by-default), but got no proper reason and motive behind this. Hence I am raising it here.
Comment From: sdeleuze
Unconfined dispatcher is used by default because it is a good fit with Reactive underneath infrastructure, as it is "not confined to any specific thread" as documented.
Next time, please wait for an answer on Stackoverflow for such question.
Comment From: jesperancinha
Unconfined dispatcher is used by default because it is a good fit with Reactive underneath infrastructure, as it is "not confined to any specific thread" as documented.
Next time, please wait for an answer on Stackoverflow for such question.
I'm glad I got this one right on Stackoverflow 😊!