Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suspending a Kotlin coroutine until a flow has a specific value

I am currently playing around with Kotlin coroutines and flows. In my scenario, a MutableStateFlow represents a connection state (CONNECTING, CONNECTED, CLOSING, CLOSED). It is also possible to login, logout and login again.

For further use of the connection, I have to check the state and wait until it is CONNECTED. If it is already CONNECTED, I can continue. If not, I have to wait until the state reaches CONNECTED. The connect() call does return immediately, the result is propagated via a callback that updates the MutableStateFlow. My current idea is to do the following:

connect()

if (connectionState.value != State.CONNECTED) { // connectionState = MutableStateFlow(State.CLOSED)

    suspendCoroutine<Boolean> { continuation ->
        scope.launch { // scope = MainScope()
            connectionState.collect {
                if (it == State.CONNECTED) {
                    continuation.resume(true)
                }
            }
        }
    }
}

// continue

As I am fairly new to the topic, I don't know if this is good practice and I was also not able to find a more suitable concept in the Kotlin documenation. Is there some better way of doing it?

like image 985
LN-12 Avatar asked Nov 23 '20 14:11

LN-12


People also ask

How do you wait for coroutine to finish Kotlin?

We can wait for the coroutine to finish by calling join() on the Job. For example, suppose we have a suspend function to download some files. We can launch this coroutine and capture the resulting job, which we can later use to join — to wait for the operation to complete.

How does suspension work in Kotlin coroutines?

Suspending functions are at the center of everything coroutines. A suspending function is simply a function that can be paused and resumed at a later time. They can execute a long running operation and wait for it to complete without blocking.

Is Kotlin flow collect blocking?

Flow is an idiomatic way in kotlin to publish sequence of values. While the flow itself suspendable, the collector will block the coroutine from proceeding further.

What is the difference between suspending vs blocking in Kotlin?

BLOCKING: Function A has to be completed before Function B continues. The thread is locked for Function A to complete its execution. SUSPENDING: Function A, while has started, could be suspended, and let Function B execute, then only resume later. The thread is not locked by Function A.


1 Answers

A while back I had the same question:

enter image description here

It is preferred to use first() to suspend till the predicate is matched.

if (connectionState.value != State.CONNECTED) {
    connectionState.first { it == State.CONNECTED }
}
like image 129
Animesh Sahu Avatar answered Oct 12 '22 00:10

Animesh Sahu