Zach Klippenstein (he/him) [MOD]
09/21/2018, 1:06 PMapi-review
branch hasn't been merged yet, but i noticed this commit deprecates the onCompletion
parameters to launch, async, etc. What's the best way to wire up channels to cancel on coroutine completion after this change? Explicit try/catch in the coroutine? (Is there a discussion about this change anywhere I could read up on?)
https://github.com/Kotlin/kotlinx.coroutines/commit/3049652ff5e3a23e35bcc82e28fb87936ed836ecZach Klippenstein (he/him) [MOD]
09/21/2018, 1:07 PMZach Klippenstein (he/him) [MOD]
09/21/2018, 2:02 PMChannel.consumes()
should also be deprecated.Vsevolod Tolstopyatov [JB]
09/21/2018, 2:09 PMWhat’s the best way to wire up channels to cancel on coroutine completion after this change?using
invokeOnCompletion
🙂 It’s deprecated only as launching argument. You still can write
val job = launch {}
job.invokeOnCompletion
What about channel closing — I’d glad to see your use-cases. Closing channel from the async.onCompletion
is rather a smell that produce
or actor
should be usedZach Klippenstein (he/him) [MOD]
09/21/2018, 3:22 PMasync
, produce
, and actor
all in one. Internally the coroutine can send on one channel, receive on another (of a different type), and return a value. Externally the builder returns an object that has a SendChannel<O>
, a ReceiveChannel<I>
, and a Deferred<R>
.
The implementation looks something like:
fun <I, O, R> CoroutineScope.foo(block: suspend FooScope<I, O>.() -> R): Foo<I,O,R> {
val inputs = Channel<I>()
val outputs = Channel<O>()
val result = async {
val scope = object : FooScope<I, O>,
ReceiveChannel<I> by inputs,
SendChannel<O> by outputs {}
return@async scope.block()
}
result.invokeOnCompletion { cause -> inputs.cancel(cause) }
result.invokeOnCompletion { cause -> outputs.cancel(cause) }
inputs.invokeOnClose { cause -> result.cancel(cause) }
outputs.invokeOnClose { cause -> result.cancel(cause) }
return object : Foo<I, O, R> {
override val inputs get() = inputs
override val outputs get() = outputs
override val result() = result
}
}
This definitely isn’t ideal – everything has to be manually wired up to cancel everything else, so I would love to find a simpler way to write it.Zach Klippenstein (he/him) [MOD]
09/21/2018, 3:22 PMasync
, actor
, and produce
builders I guess, but then I’m starting three coroutines when I only need one, which seems wasteful.Vsevolod Tolstopyatov [JB]
09/21/2018, 4:54 PMinvokeOnCompletion
, so everything should work for you as before