Hey!
TLDR: add kotlin extension function to BatchLoaderRegistry to simplify registration of a suspend function.
Request
If you want to register a "mapped batch loader" in Spring GraphQL, you must/can provide a function that returns a Mono(source).
To register a suspend function, you can provide this function as: mono() { /*suspend/* } .
There is a problem with this approach: it fails to properly propagate/restore ThreadLocalAccessor values (and also tracing information I think).
You can reproduce this if you access SecurityContextHolder.getContext().authentication before and after the mono call.
If authentication used to be non-null before the mono call (e.g. TestingAuthenticationToken), it will suddenly be null after it.
In Spring Framework 7, a coroutine element called PropagationContextElement() was introduced to solve this (docs).
It would be nice to have kotlin extensions to register a suspend function in the correct way:
fun <K, V> BatchLoaderRegistry.RegistrationSpec<K, V>.registerSuspendMappedBatchLoader(
dispatcher: CoroutineDispatcher = Executors.newVirtualThreadPerTaskExecutor().asCoroutineDispatcher(),
batchLoader: suspend (keys: Set<K>, env: BatchLoaderEnvironment) -> Map<K, V>,
) {
this.registerMappedBatchLoader { keys: Set<K>, env: BatchLoaderEnvironment ->
mono(dispatcher + PropagationContextElement()) {
batchLoader(keys, env)
}
}
}
fun <K, V> BatchLoaderRegistry.RegistrationSpec<K, V>.registerSuspendMappedBatchLoader(
dispatcher: CoroutineDispatcher = Dispatchers.Default,
batchLoader: suspend (keys: Set<K>) -> Map<K, V>,
) {
this.registerMappedBatchLoader { keys: Set<K>, _: BatchLoaderEnvironment ->
mono(dispatcher + PropagationContextElement()) {
batchLoader(keys)
}
}
}
NOTE: I'm not sure about the default value of the dispatcher though.
Could we add such an extension function to Spring GraphQL?
Hey!
TLDR: add kotlin extension function to
BatchLoaderRegistryto simplify registration of asuspendfunction.Request
If you want to register a "mapped batch loader" in Spring GraphQL, you must/can provide a function that returns a
Mono(source).To register a
suspend function, you can provide this function as:mono() { /*suspend/* }.There is a problem with this approach: it fails to properly propagate/restore
ThreadLocalAccessorvalues (and also tracing information I think).You can reproduce this if you access
SecurityContextHolder.getContext().authenticationbefore and after themonocall.If authentication used to be non-null before the mono call (e.g.
TestingAuthenticationToken), it will suddenly benullafter it.In Spring Framework 7, a coroutine element called
PropagationContextElement()was introduced to solve this (docs).It would be nice to have kotlin extensions to register a suspend function in the correct way:
NOTE: I'm not sure about the default value of the dispatcher though.
Could we add such an extension function to Spring GraphQL?