Skip to content

Commit

Permalink
Allow for CoroutineContext in invokeSuspendingFunction
Browse files Browse the repository at this point in the history
This commit adds an overloaded version of invokeSuspendingFunction
that specifies a CoroutineContext, instead of using
Dispatchers.Unconfined.

Closes gh-27193
  • Loading branch information
poutsma committed Sep 27, 2022
1 parent dd3e3b2 commit f80fbe3
Showing 1 changed file with 25 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Objects;

import kotlin.Unit;
import kotlin.coroutines.CoroutineContext;
import kotlin.jvm.JvmClassMappingKt;
import kotlin.reflect.KClass;
import kotlin.reflect.KClassifier;
Expand Down Expand Up @@ -66,17 +67,39 @@ public static <T> Deferred<T> monoToDeferred(Mono<T> source) {
(scope, continuation) -> MonoKt.awaitSingleOrNull(source, continuation));
}

/**
* Invoke a suspending function and converts it to {@link Mono} or
* {@link Flux}. Uses an {@linkplain Dispatchers#getUnconfined() unconfined}
* dispatcher.
* @param method the suspending function to invoke
* @param target the target to invoke {@code method} on
* @param args the function arguments
* @return the method invocation result as reactive stream
*/
public static Publisher<?> invokeSuspendingFunction(Method method, Object target,
Object... args) {
return invokeSuspendingFunction(Dispatchers.getUnconfined(), method, target, args);
}

/**
* Invoke a suspending function and converts it to {@link Mono} or
* {@link Flux}.
* @param context the coroutine context to use
* @param method the suspending function to invoke
* @param target the target to invoke {@code method} on
* @param args the function arguments
* @return the method invocation result as reactive stream
* @since 6.0
*/
@SuppressWarnings("deprecation")
public static Publisher<?> invokeSuspendingFunction(Method method, Object target, Object... args) {
public static Publisher<?> invokeSuspendingFunction(CoroutineContext context, Method method, Object target,
Object... args) {

KFunction<?> function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method));
if (method.isAccessible() && !KCallablesJvm.isAccessible(function)) {
KCallablesJvm.setAccessible(function, true);
}
Mono<Object> mono = MonoKt.mono(Dispatchers.getUnconfined(), (scope, continuation) ->
Mono<Object> mono = MonoKt.mono(context, (scope, continuation) ->
KCallables.callSuspend(function, getSuspendedFunctionArgs(target, args), continuation))
.filter(result -> !Objects.equals(result, Unit.INSTANCE))
.onErrorMap(InvocationTargetException.class, InvocationTargetException::getTargetException);
Expand Down

0 comments on commit f80fbe3

Please sign in to comment.