Skip to content

Commit e7d7253

Browse files
koenpuntrstoyanchev
authored andcommitted
Support use of dataloader from suspend function
Rudimentary implementation to support returning a `CompletableFuture` from a suspend function. `CoroutinesUtils.invokeSuspendingFunction` wraps the return value of the function in a `Mono` (or `Flux`). But it also does this when a `CompletableFuture` is returned, and thus results in a `Mono<CompletableFuture<?>>`, which isn't captured by graphql-java, and thus the dataloader is never dispatched. By unwrapping the future, and _converting_ it to a mono (as opposed to wrapping), the dataloader is dispatched correctly. See gh-653
1 parent 71b1f58 commit e7d7253

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethodSupport.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import graphql.GraphQLContext;
2828
import io.micrometer.context.ContextSnapshot;
29+
import org.springframework.data.util.KotlinReflectionUtils;
2930
import reactor.core.publisher.Mono;
3031

3132
import org.springframework.core.CoroutinesUtils;
@@ -81,7 +82,18 @@ protected Object doInvoke(GraphQLContext graphQLContext, Object... argValues) {
8182
Method method = getBridgedMethod();
8283
try {
8384
if (KotlinDetector.isSuspendingFunction(method)) {
84-
return CoroutinesUtils.invokeSuspendingFunction(method, getBean(), argValues);
85+
Object result = CoroutinesUtils.invokeSuspendingFunction(method, getBean(), argValues);
86+
87+
Class<?> returnType = KotlinReflectionUtils.getReturnType(method);
88+
89+
if (CompletableFuture.class.isAssignableFrom(returnType)) {
90+
@SuppressWarnings("unchecked")
91+
Mono<CompletableFuture<?>> mono = (Mono<CompletableFuture<?>>)result;
92+
// Unwrap nested CompletableFuture
93+
return mono.flatMap(Mono::fromFuture);
94+
}
95+
96+
return result;
8597
}
8698
Object result = method.invoke(getBean(), argValues);
8799
return handleReturnValue(graphQLContext, result);

0 commit comments

Comments
 (0)