https://kotlinlang.org logo
#coroutines
Title
# coroutines
p

Pacane

03/31/2020, 12:26 PM
Hi, I'm trying to transform a callback-based function to a coroutine. Here's what I have so far
Copy code
suspend fun fastSubscribe(path: String): Value =
            suspendCancellableCoroutine { cont: CancellableContinuation<Value> ->
                val handler = object : Handler<SubscriptionValue> {
                    override fun handle(event: SubscriptionValue) {
                        requester.unsubscribe(path, this)
                        cont.resume(event.value)
                    }
                }

                requester.subscribe(path, handler)
            }
Here I want to finish the execution with the value in the callback when I have one, but I'd like to add a timeout for if I never get a value (ie: when
handle
is never called) I think I should use a
withTimeout
in there but I don't know where exactly. On timeout I need to call
requester.unsubscribe(handler)
, so having the
withTimeout
on the call site of
fastSubscribe
isn't really a solution. Is there anything I can do with this?
t

tseisel

03/31/2020, 12:34 PM
Since
withTimeout
will try to cancel the running coroutine after the time limit has been reached, you could register a listener with
cont.invokeOnCancellation
to dispose the subscription if its result has not been received.
s

streetsofboston

03/31/2020, 12:36 PM
The 'withTimeout' would go above/around the suspendCancellableCoroutine, but there you won't have access to the 'handler' to unregister it.... Tricky. Not sure, but you could try to use a call to 'async' instead and wrap the 'withTimeout' around the call to 'await()' of the 'async'....
Ah.... @tseisel answer is great. You can examine in the invokeOnCancellation how continuation ended or how it was cancelled.
p

Pacane

03/31/2020, 12:39 PM
Yes that's what I'm trying to do right now, seems to be a good path
Works perfectly! thanks @tseisel
2 Views