---
title: "Comment by Shreyas Patil on \"WhileSubscribed(5000)\" | Hashnode"
description: "Thanks, it&#39;s really great writeup 👍. By the way, instead of CompletableDeferred , why don&#39;t you use suspendCancellableCoroutine by which you can also s"
url: "https://hashnode.com/posts/whilesubscribed5000/630e96e456df9e8e502575df/comment/630f1f4575af73ad1f0603ec"
---

[Discussion](https://hashnode.com/posts/whilesubscribed5000/630e96e456df9e8e502575df)

Comment [WhileSubscribed(5000)](https://hashnode.com/posts/whilesubscribed5000/630e96e456df9e8e502575df)

[Shreyas Patil](https://hashnode.com/@patilshreyas)

[Aug 31, 2022](https://hashnode.com/posts/whilesubscribed5000/630e96e456df9e8e502575df/comment/630f1f4575af73ad1f0603ec)

Thanks, it's really great writeup 👍.

By the way, instead of `CompletableDeferred`, why don't you use `suspendCancellableCoroutine` by which you can also support cancelling registered callback if Flow is by chance terminated/cancelled/?

Let's say, this is how it looks if implemented with `suspendCancellableCoroutine`:

```
object WhileSubscribedOrRetained : SharingStarted {

    private val handler = Handler(Looper.getMainLooper())

    override fun command(subscriptionCount: StateFlow<Int>): Flow<SharingCommand> =
        subscriptionCount
            .transformLatest { count ->
                if (count > 0) {
                    emit(SharingCommand.START)
                } else {
                    awaitChoregrapherFramePostFrontOfQueue()
                    emit(SharingCommand.STOP)
                }
            }
            .dropWhile { it != SharingCommand.START }
            .distinctUntilChanged()

    override fun toString(): String = "WhileSubscribedOrRetained"

    @OptIn(InternalCoroutinesApi::class)
    private suspend fun awaitChoregrapherFramePostFrontOfQueue() {
        suspendCancellableCoroutine<Unit> { cont ->
            val frameCallback = Choreographer.FrameCallback {
                handler.postAtFrontOfQueue {
                    handler.post {
                        if (!cont.isCompleted) {
                            cont.resume(Unit)
                        }
                    }
                }
            }

            Choreographer.getInstance().postFrameCallback(frameCallback)

            cont.invokeOnCancellation {
                Choreographer.getInstance().removeFrameCallback(frameCallback)
            }
        }
    }
}
```
