I wanted to create a context-based logger in a reactive Spring environment using Kotlin coroutines.
Using configuration: https://github.com/archie-swif/webflux-mdc/tree/master/src/main/java/com/example/webfluxmdc
I have created a GitHub "playground-code": https://github.com/Numichi/reactive-kotlin-coroutines-mdc README.md is contain responses of controller.
Run timeline /work/X and /notwork/X:
/(not)work/20 [--------------------]
/(not)work/10 [ ---------- ]
/(not)work/1 [ - ]
We can see there is a moment when all requests runs same time.
So, for "work", everything works fine, but I don't understand why I didn't get like the result for "work". The data slips. I'm sure the delay is the cause, but I don’t see the reasons and why. Can you help explain why? And how can this be fixed?
Expected operation:
Should get back same data in { data: X, ... }
where ?data=X
@Component
class Filter : WebFilter {
override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
return chain.filter(exchange)
.contextWrite {
it.putNonNull("data", exchange.request.queryParams["data"]?.get(0))
}
}
}
@RestController
class MdcController {
@GetMapping("work/{delay}")
suspend fun work(@PathVariable delay: Int): Map<String, String> {
MDC.put("threadName", Thread.currentThread().name)
return withContext(MDCContext()) {
delay((delay * 1000).toLong()) // <-- IN the withContext
MDC.put("threadName-in-context", Thread.currentThread().name)
MDC.getCopyOfContextMap()
}
}
@GetMapping("notwork/{delay}")
suspend fun notwork(@PathVariable delay: Int): Map<String, String> {
MDC.put("threadName", Thread.currentThread().name)
delay((delay * 1000).toLong()) // <-- OUT the withContext
return withContext(MDCContext()) {
MDC.put("threadName-in-context", Thread.currentThread().name)
MDC.getCopyOfContextMap()
}
}
}