Has anyone dealt with structured concurrency issue...
# graphql
j
Has anyone dealt with structured concurrency issues due to
FunctionDataFetcher::runSuspendingFunction
using
GlobalScope
instead of an existing scope? Right now, I can put a scope in the context, and in my Query object do something like:
Copy code
fun cancellable(env: DataFetchingEnvironment): CompletableFuture<String> {
    return env.getContext<CoroutineScope>().future {
        delay(100)
        "result"
    }
}
And then cancel a running query via the context scope's
.cancel()
I'd like to be able to do something like:
Copy code
suspend fun cancellable(): String {
    delay(100)
    return "result"
}
But when I do so, the coroutineContext is not inherited (eg, MDCContext() doesn't place MDC values for logging) and cancelling the parent scope doesn't cancel the created coroutine. I can make it work with a
FunctionDataFetcher
subclass that looks for a scope-implementing context and uses that (falling back to GlobalScope if there isn't one). Does that seem like the right approach? Would a PR doing that in
FunctionDataFetcher
be welcome?
(Also, it seems like ideally the
runSuspendingFunction
could pick up an existing scope via the call stack instead of having to pass it through via context, but I can't seem to get that to work, I think because bridging suspend -> nonsuspend -> suspend apparently losing the scope?)
d
unfortunately in the current implementation (in
graphql-kotlin
) we don’t have native query execution that would support true structured concurrency so yes you would need custom data fetcher that would be handling proper parent/child relationship of the target resolvers
and yes once you move from suspendable function to regular function you loose the scope information
j
ok, thanks for confirming. Opened up https://github.com/ExpediaGroup/graphql-kotlin/pull/879 to address this in
FunctionDataFetcher
but can use a custom one for now in our projects.