Hi there! I’m working on an open source library I ...
# coroutines
p
Hi there! I’m working on an open source library I released few months ago to easily launch external process from Kotlin: https://github.com/pgreze/kotlin-process/pull/7 I would like to add cancellation support but the way I found so far seems not covering all cases (see PR description). For example, is it worth having a third async operation actively monitoring the isActive state? Thank you in advance for any support 🙏
e
why not something like
Copy code
suspend fun process(vararg command: String) = suspendCancellableCoroutine { continuation ->
    val process = ProcessBuilder(*command).start()
    continuation.invokeOnCancellation { process.destroy() }
    continuation.resume(process.waitFor()) { }
}
n
FYI:
runInterruptible
can help break out of blocking methods like
Process.waitFor
p
@ephemient this seems really helpful, let me try it and come back to you if it worked or not 👍
@Nick Allen could you give me more insights on this function? I found this discussion but I’m wondering what’s happening in case of cancellation
e
runInterruptible
is pretty similar and also throws a
InterruptedException
which can help break out of some blocking functions (such as
waitFor
)
not exactly needed here because
.destroy()
will cause
.waitFor()
to finish anyway
using
runInterruptible
would look something like this:
Copy code
suspend fun process(vararg command: String): Int {
    val process = ProcessBuilder(*command).start()
    try {
        return runInterruptible {
            process.waitFor()
        }
    } finally {
        process.destroy()
    }
}
p
@ephemient thanks again for your insights.
invokeOnCancellation
seems what I need but always good to know the alternatives 🙂
@ephemient I tried using
invokeOnCancellation
but I could not use
awaitAll
inside, and everything I tried were just more verbose alternatives of my
runInterruptible
experiment. If you don’t mind reviewing it, here is my current working code: https://github.com/pgreze/kotlin-process/pull/7/files
n
Perhaps you'd prefer to just destroy the process when the IO related scope is done? Register once the process is created:
coroutineContext[Job]!!.invokeOnCompletion { process.destroy()}
p
@Nick Allen I was trying to avoid calling
destroy
unless necessary, but not sure what’s the best practice regarding this function…