vishna
06/05/2019, 3:33 PMstreetsofboston
06/05/2019, 3:52 PMsuspendCoroutine
and its Continuation
is mostly used for handling 3rd party (async) callbacks.
I would rewrite your function to something like this:
suspend infix fun InputStream.weaveTo(outputStream: OutputStream) = coroutineScope {
val bytes = ByteArray(1024)
while (true) {
ensureActive()
val read = read(bytes)
if (read == -1) {
break
}
outputStream.write(bytes, 0, read)
}
}
vishna
06/05/2019, 4:05 PMensureActive()
be here exactly? I want something that gets cancelled as soon as someone cancels the outer coroutine… e.g. job.cancel()
and reason would be avoiding further weaving from the input to the output as there still could be a lot of bytes to read/writeelizarov
06/05/2019, 4:40 PMensureActive
throws exception when cancelled.elizarov
06/05/2019, 4:41 PMcoroutineScope
. Just write a suspend function and do if (!coroutineContext.isActive) break
inside your loop. Same effect as your original code with suspendCancellableCoroutine
. There is no reason to use it in your code. More code, but zero added value.vishna
06/05/2019, 6:00 PMensureActive
is a hoax (just wouldn't import 🤷♂️)... anyway without the isActive
check this would otherwise run till input is exhausted, is that correct?streetsofboston
06/05/2019, 6:01 PMgildor
06/06/2019, 12:54 AMsuspend infix fun InputStream.weaveTo(outputStream: OutputStream) = <http://Dispatchers.IO|Dispatchers.IO> { // shortcut for withContext
val bytes = ByteArray(1024)
while (coroutineContext.isActive) {
val read = read(bytes)
if (read == -1) {
break
}
outputStream.write(bytes, 0, read)
}
}
streetsofboston
06/06/2019, 2:05 AMcoroutineContext
property available for suspend funs 😀gildor
06/06/2019, 2:09 AMgildor
06/06/2019, 2:13 AMwrite
with isActive
, it will make cancellation faster, because read may be pretty slow (especially for reading from network) and no need to wait also writing before cancel