carbaj0

    carbaj0

    1 year ago
    class ProduceStateScopeImpl<T>(
        state: MutableState<T>,
        override val coroutineContext: CoroutineContext
    ) : ProduceStateScope<T>, MutableState<T> by state {
    
        override suspend fun awaitDispose(onDispose: () -> Unit): Nothing {
            try {
                suspendCancellableCoroutine<Nothing> { }
            } finally {
                onDispose()
            }
        }
    }
    Why
    suspendCancellableCoroutine<Nothing> { }
    is being executed?
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Presumably because something is calling
    awaitDispose
    ?
    Also this question has nothing to do with compose, did you mean to post in #coroutines ?
    Adam Powell

    Adam Powell

    1 year ago
    It's a class from compose-runtime 🙂
    It's the same basic pattern from channelFlow's
    awaitClose
    carbaj0

    carbaj0

    1 year ago
    Thanks both for the answers
    I will try to find out more about this, because it isn't clear to me
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Can you elaborate on your question a bit? Why would you expect
    suspendCancellableCoroutine
    not to be executed?
    carbaj0

    carbaj0

    1 year ago
    when i saw the empty block i thought that nothing occurs
    but of course the cancellation occurs anyway
    public suspend inline fun <T> suspendCancellableCoroutine(
        crossinline block: (CancellableContinuation<T>) -> Unit
    ): T =
        suspendCoroutineUninterceptedOrReturn { uCont ->
            val cancellable = CancellableContinuationImpl(uCont.intercepted(), resumeMode = MODE_CANCELLABLE)
            /*
             * For non-atomic cancellation we setup parent-child relationship immediately
             * in case when `block` blocks the current thread (e.g. Rx2 with trampoline scheduler), but
             * properly supports cancellation.
             */
            cancellable.initCancellability()
            block(cancellable)
            cancellable.getResult()
        }
    I was expecting a
    coroutineContext.cancel ()
    or something like that 😅
    Adam Powell

    Adam Powell

    1 year ago
    Ah, yeah that happens when the underlying LaunchedEffect restarts for a new key or leaves the composition 🙂
    carbaj0

    carbaj0

    1 year ago
    there are a new function in the kotlinx.coroutines a little more idiomatic,
    awaitCancellation()
    /**
     * Suspends until cancellation, in which case it will throw a [CancellationException].
     *
     * This function returns [Nothing], so it can be used in any coroutine,
     * regardless of the required return type.
     */
    public suspend fun awaitCancellation(): Nothing = suspendCancellableCoroutine {}
    is the same implementation, no surprises 😆
    Adam Powell

    Adam Powell

    1 year ago
    Yep, we added the
    awaitDispose
    scoped method before
    awaitCancellation
    came in 🙂