Skip to content

Commit 492f993

Browse files
committed
fix: respect custom coroutine scope when calling blocking functions in a data fetcher
When running blocking function data fetcher it does not respect coroutine scope provided in the GraphQL context. In my project we're creating custom a coroutine scope in order to propagate MDC and OTEL contexts in a coroutine like this: ``` CoroutineScope(MDCContext() + Dispatchers.IO + Context.current().asContextElement()) ``` (here `Context` is an instance of OTEL context). This works well in suspended functions since they are using the context however normal functions are not using this context and therefore none of the OTEL context (trace id etc) is propagated.
1 parent 7412ed8 commit 492f993

File tree

1 file changed

+10
-3
lines changed
  • generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/execution

1 file changed

+10
-3
lines changed

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/execution/FunctionDataFetcher.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import graphql.schema.DataFetcher
2424
import graphql.schema.DataFetchingEnvironment
2525
import kotlinx.coroutines.CoroutineScope
2626
import kotlinx.coroutines.future.future
27+
import kotlinx.coroutines.runBlocking
2728
import java.lang.reflect.InvocationTargetException
2829
import java.util.concurrent.CompletableFuture
2930
import kotlin.coroutines.EmptyCoroutineContext
@@ -60,7 +61,7 @@ open class FunctionDataFetcher(
6061
if (fn.isSuspend) {
6162
runSuspendingFunction(environment, parameterValues)
6263
} else {
63-
runBlockingFunction(parameterValues)
64+
runBlockingFunction(environment, parameterValues)
6465
}
6566
} else {
6667
null
@@ -123,8 +124,14 @@ open class FunctionDataFetcher(
123124
* Once all parameters values are properly converted, this function will be called to run a simple blocking function.
124125
* If you need to override the exception handling you can override this method.
125126
*/
126-
protected open fun runBlockingFunction(parameterValues: Map<KParameter, Any?>): Any? = try {
127-
fn.callBy(parameterValues)
127+
protected open fun runBlockingFunction(
128+
environment: DataFetchingEnvironment,
129+
parameterValues: Map<KParameter, Any?>
130+
): Any? = try {
131+
val coroutineScope = environment.graphQlContext.getOrDefault(CoroutineScope(EmptyCoroutineContext))
132+
runBlocking(coroutineScope.coroutineContext) {
133+
fn.callBy(parameterValues)
134+
}
128135
} catch (exception: InvocationTargetException) {
129136
throw exception.cause ?: exception
130137
}

0 commit comments

Comments
 (0)