SuspendToFutureAdapter


object SuspendToFutureAdapter


A utility for launching suspending calls scoped and managed by a returned ListenableFuture, used for adapting Kotlin suspending APIs to be callable from the Java programming language.

Summary

Public functions

ListenableFuture<T>
<T : Any?> launchFuture(
    context: CoroutineContext,
    launchUndispatched: Boolean,
    block: suspend CoroutineScope.() -> T
)

Launch block in context, returning a ListenableFuture to manage the launched operation.

Public functions

launchFuture

Added in 1.2.0
fun <T : Any?> launchFuture(
    context: CoroutineContext = EmptyCoroutineContext,
    launchUndispatched: Boolean = true,
    block: suspend CoroutineScope.() -> T
): ListenableFuture<T>

Launch block in context, returning a ListenableFuture to manage the launched operation. block will run synchronously to its first suspend point, behaving as CoroutineStart.UNDISPATCHED by default; set launchUndispatched to false to override and behave as CoroutineStart.DEFAULT.

launchFuture can be used to write adapters for calling suspending functions from the Java programming language, e.g.

@file:JvmName("FancyServices")

fun FancyService.requestAsync(
args: FancyServiceArgs
): ListenableFuture<FancyResult> = SuspendToFutureAdapter.launchFuture {
request(args)
}

which can be called from Java language source code as follows:

final ListenableFuture<FancyResult> result = FancyServices.requestAsync(service, args);

If no kotlinx.coroutines.CoroutineDispatcher is provided in context, Dispatchers.Main is used as the default. ListenableFuture.get should not be called from the main thread prior to the future's completion (whether it was obtained from SuspendToFutureAdapter or not) as any operation performed in the process of completing the future may require main thread event processing in order to proceed, leading to potential main thread deadlock.

If the operation performed by block is known to be safe for potentially reentrant continuation resumption, immediate dispatchers such as Dispatchers.Unconfined may be used as part of context to avoid additional thread dispatch latency. This should not be used as a means of supporting clients blocking the main thread using ListenableFuture.get; this support can be broken by valid internal implementation changes to any transitive dependencies of the operation performed by block.