2 years ago

#53880

test-img

Numichi

Why MDC & MDCContext happened in an unexpected ran? The data slips

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()
        }
    }
}

spring-webflux

slf4j

kotlin-coroutines

project-reactor

mdc

0 Answers

Your Answer

Accepted video resources