Created
September 21, 2021 16:19
-
-
Save DRSchlaubi/fa4c9cdbbd8ef5218c777f1a6b2d06d8 to your computer and use it in GitHub Desktop.
GoogleFutureUtil
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dev.schlaubi.util | |
import com.google.api.core.ApiFuture | |
import com.google.common.util.concurrent.MoreExecutors | |
import kotlinx.coroutines.CancellableContinuation | |
import kotlinx.coroutines.suspendCancellableCoroutine | |
import java.util.concurrent.ExecutionException | |
import kotlin.coroutines.resume | |
import kotlin.coroutines.resumeWithException | |
/** | |
* Suspends an [ApiFuture]. | |
*/ | |
public suspend fun <T> ApiFuture<T>.await(): T { | |
// fast path when ApiFuture is already done (does not suspend) | |
if (isDone) { | |
try { | |
@Suppress("BlockingMethodInNonBlockingContext") | |
return get() | |
} catch (e: ExecutionException) { | |
throw e.cause ?: e // unwrap original cause from ExecutionException | |
} | |
} | |
// slow path -- suspend | |
return suspendCancellableCoroutine { cont: CancellableContinuation<T> -> | |
this.addListener( | |
{ | |
try { | |
cont.resume(get()) | |
} catch (e: ExecutionException) { | |
cont.resumeWithException(e.cause ?: e) // unwrap original cause from ExecutionException | |
} | |
}, | |
MoreExecutors.directExecutor() | |
) | |
cont.invokeOnCancellation { | |
cancel(false) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment