If I have a resource inside a `Flow` , what’s the ...
# coroutines
s
If I have a resource inside a
Flow
, what’s the best way to call something when the context it’s running in is cancelled? i.e. when the flow is cancelled, I need to call `process.destroy()`:
Copy code
actual fun run(command: String): Flow<String> = flow {
        val split = command.split(' ')
        val process = ProcessBuilder(split).apply {
            redirectErrorStream(true)
        }.start()

        process.inputStream.source().use { processSource ->
            processSource.buffer().use { bufferedProcessSource ->
                while (true) {
                    val line = bufferedProcessSource.readUtf8Line() ?: break
                    emit(line)
                }
            }
        }
    }.flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
b
You can use
currentCoroutineContext
from
flow {}
for checking if it still active
So you can simply switch from
while(true)
to
while (currentCoroutineContext().isActive)
. Also, I believe
emit
will throw cancellation exception if flow's collector was cancelled (since 1.3.7). Then you can call
process.destroy()
in finally block
s
Thanks for the advise. This looks good.
Is there any difference between
currentCoroutineContext()
and
coroutineContext
? It doesn’t look like it
it’s hard to be sure with compiler magic implicit variables like this though.
b
yes, there is a difference, sometimes coroutineContext may be ambiguous - in case if you have an access to CoroutineScope as
this
(e.g. if you write
flow { }
inside `coroutineScope`/`launch`/`async` etc or if you write the flow operator as an extension function of CoroutineScope, or something like that). There is an example in the link I mentioned where coroutineContext will refer to the wrong context.