Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting status updates from a coroutine

Consider an asynchronous API that reports progress on its operations:

suspend fun operationWithIO(input: String, progressUpdate: (String) -> Unit): String {
    withContext(Dispatchers.IO) {
        // ...
    }
}

Is it possible to implement calls to progressUpdate such that callbacks are handled on the caller's dispatcher? Or is there a better way to deliver status updates back to the caller?

like image 838
gladed Avatar asked Nov 03 '25 20:11

gladed


1 Answers

You should send progress updates on a channel. That will allow the caller to listen to the channel using whatever dispatcher it wants.

suspend fun operationWithIO(input: String, progressChannel: Channel<String>): String {
    withContext(Dispatchers.IO) {
        // ...

        progressChannel.send("Done!")
        progressChannel.close()
    }
}

The caller can use it by doing something like this:

val progressChannel = Channel<String>()

someScope.launch {
    operationWithIO(input, progressChannel)
}

// Remember the call to progressChannel.close(), so that this iteration stops.
for (progressUpdate in progressChannel) {
    println(progressUpdate)
}
like image 130
marstran Avatar answered Nov 07 '25 00:11

marstran