Hey :wave: I'm trying to use `suspendCancellableCo...
# coroutines
a
Hey 👋 I'm trying to use
suspendCancellableCoroutine
to bridge some 3rd party API in my app. It's working OK-ish but I'm wondering how reliable it is considering the callback I need to implement requires returning some values, e.g.
Copy code
suspend fun displayFoo() {
    val foo = getFoo()
    delay(10_000)
    println(foo)
}

suspend fun getFoo(): Foo = suspendCancellableCoroutine { continuation ->
    val callback = FooLoader
        .addListener(object : RequestListener<Foo> {
            override fun onLoadFailed(e: FooException): Boolean {
                continuation.resumeWithException(e)
                return false
            }

            override fun onLoadSuccessful(foo: Foo): Boolean {
                continuation.resume(foo)
                return false
            }
        })
        .load()

    continuation.invokeOnCancellation {
        callback.cancel()
    }
}
How is this actually working? Does the thread calling
onLoadSuccessful
execute the full
delay(10_000)
before returning
return false
or is it executed as soon as the calling thread is "free" (because
delay
is suspending, not blocking)? I'm also wondering what would happen if the continuation failed e.g.
Copy code
suspend fun displayFoo() {
    val foo = getFoo()
    delay(10_000)
    throw NPE
}
n
Side note: Please post code and further clarifications in thread. No,
continuation.resume(foo)
will not block when the resumed coroutine later suspends. Usually, it's just adding to a CoroutineDispatcher's event queue so it's not waiting at all. In some cases like with Dispatchers.Unconfined or Dispatchers.Main.immediate it will actually start running the resumed code directly but it will return as soon as the calling thread is free.
suspendCancellableCoroutine
kinda just exposes how suspend methods actually work when they suspend. When they suspend, they actually just setup code to invoke the continuation (hidden parameter added by suspend keyword ) later and then they return right away. This returning right away is how it frees up the thread. So in the compiled code,
delay(10_000)
actually just sets up a timer callback, and then returns immediately and displayFoo returns immediately and all the way up until it get's to the CoroutineDispatcher.
println(foo)
and any other code waiting to run is wrapped up in the time callback.
Google "kotlin coroutines under the hood" and you should see some more details about how coroutines are implemented. I know there's was a decent KotlinConf video but not finding it at the moment,