quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.72k stars 2.67k forks source link

Feature Request - default CoroutineContext #36875

Open pkozakCC opened 11 months ago

pkozakCC commented 11 months ago

Discussed in https://github.com/quarkusio/quarkus/discussions/36738

Originally posted by **pkozakCC** October 27, 2023 There are cases where the default `CoroutineContext` has to be modified for all suspendable RestEasy Resource method calls, for example in order to add a custom `CoroutineContext.Element` for every request, that would hold application-specific details, such as tenant ID (which is precisely my case btw). This can be done manually, but it's tedious and error-prone. It would be nice to introduce a mechanism that would make it possible to modify the default CoroutineContext. It can be either of a form CoroutineWebFilter, that would return a suspendable function and would respect the context in the downstream, e.g.: ```kotlin suspend fun filter( serverWebExchange: ServerWebExchange, webFilterChain: CoroutineWebFilterChain, ): Mono { return withContext(MyCustomCoroutineContextElement()) { webFilterChain.filter(serverWebExchange) } } interface CoroutineWebFilterChain { suspend fun filter(serverWebExchange: ServerWebExchange): Mono } ``` Or similarly to the Spring approach (links below) - registering a list of `CoroutineContext.Element` in a filter (per request) After: - https://stackoverflow.com/questions/77370339/quarkus-default-coroutines-context?noredirect=1#comment136401015_77370339 Spring Webflux approach for the issue (which will be released in 6.1) - current implementation of CoWebFilter does not respect the `CoroutineContext` changes: - https://github.com/spring-projects/spring-framework/issues/27522 - https://github.com/spring-projects/spring-framework/commit/b0aa004d9db74b42d7d17883ed490388261ed96e
quarkus-bot[bot] commented 11 months ago

/cc @evanchooly (kotlin), @geoand (kotlin)

geoand commented 11 months ago

Do you have some example of what exactly you are trying to do? I am asking because I would like to get a sense of what problem we are trying to solve here.

Thanks

mschorsch commented 11 months ago

The author would like to have a possibility to modify the CoroutineContext before calling the resteasy reactive endpoint, with the aim of storing additional data in the CoroutineContext. This data would then be automatically available via the CoroutineContext in all suspendable resteasy reactive endpoints. The advantage of the CoroutineContext is that it is automatically propagated by the Kotlin coroutines and therefore no longer needs to be managed by the user. A typical use case is the use of the MDC (https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-slf4j/kotlinx.coroutines.slf4j/-m-d-c-context/). In this case, the author probably wants to pass the tenantId for all resteasy reactive resources.

+1

geoand commented 11 months ago

The author would like to have a possibility to modify the CoroutineContext before calling the resteasy reactive endpoint, with the aim of storing additional data in the CoroutineContex

Yeah, I get that. What I want to see is some pseudo-example of what this would be used for

cogman commented 10 months ago

@geoand here's what I'd like to do.

@GET
suspend fun getIt(id: Int): It {
  MDC.put("get.id", id)
  return withContext(Dispatcher.IO) {
    dao.getIt(id)
  }
}

With a default coroutine context (or something like it). I could set it up as

  fun defaultSetup(rootContext: Context): Context {
    return rootContext.plus(MDCContext())
  }

This would propagate MDC values through coroutine calls (which is what I want to do).

In order to do this as of now, I have to do something like this on every endpoint

  fun getIt(id: Int): It = withContext(MDCContext()) {
    return@withContext etc()
  }
geoand commented 10 months ago

Thanks for the update!

geoand commented 10 months ago

@cogman I think I have an idea of how to make this work, but what would be super helpful in testing it would be if you could attach a sample application where you are using the feature you mention above.

Thanks

geoand commented 4 months ago

@cogman ^