dave08
01/02/2020, 2:28 PMcallbackFlow
, when should I use cancel(CancellationException("....", e))
and when should I just throw the exception? Is there any difference?Dominaezzz
01/02/2020, 2:43 PMcancel
somewhere internally (the channel has to be released somehow, right?).
I guess calling cancel
is a bit better since you can specify more info about cancellation with a string.dave08
01/02/2020, 2:55 PMCancellationException
there, shouldn't cancel
just recieve its parameters directly...? It seems like that function only takes in a CancellationException
anyways...Adam Powell
01/02/2020, 3:59 PMAdam Powell
01/02/2020, 4:01 PMcallbackFlow
uses a ProducerScope
that is backed by a channel. Your callbackFlow
is the sender and the downstream collector is the receiverAdam Powell
01/02/2020, 4:01 PMclose(cause: Throwable)
, not cancel.Adam Powell
01/02/2020, 4:04 PMcancel
method is in scope as an extension for CoroutineScope
- the scope that you can launch into for parallel decomposition, etc. It's not for reporting errors. That's why it restricts you to CancellationException
only.dave08
01/02/2020, 4:11 PMdave08
01/02/2020, 4:15 PMclose
be called anyways on the channel in such a case?Adam Powell
01/02/2020, 4:15 PMAdam Powell
01/02/2020, 4:24 PMdave08
01/02/2020, 4:33 PMdave08
01/02/2020, 4:34 PMdave08
01/02/2020, 4:35 PMAdam Powell
01/02/2020, 4:40 PMdave08
01/02/2020, 4:41 PMAdam Powell
01/02/2020, 4:41 PMAdam Powell
01/02/2020, 4:41 PMclose(e)
to the `callbackFlow`'s channel instead - that will make the receiver (the flow) resume with the close exceptionAdam Powell
01/02/2020, 4:42 PMdave08
01/02/2020, 4:43 PMcancel
since it closes the channel too, or do you still think close
should be used?Adam Powell
01/02/2020, 4:43 PMclose
. When it comes to channels close
is the sender-side operation, cancel
is the receiver-side operation.Adam Powell
01/02/2020, 4:44 PMcancel
on a channel means, "I cannot, will not receive any more items, let the sender know, and any still lingering in the buffer will be lost."Adam Powell
01/02/2020, 4:45 PMclose
means, "here's the end of this sequence of items and possibly a throwable cause if the end-of-sequence is happening for an exceptional reason." All of the items sent to the channel before it will still be received before the close signal is.dave08
01/02/2020, 4:46 PMcancel
on the ProducerScope
not the cancel
on the actual channel...?Adam Powell
01/02/2020, 4:48 PMProducerScope
implements SendChannel
but not ReceiveChannel
, the channel-cancel method isn't even availableAdam Powell
01/02/2020, 4:50 PMCoroutineScope
, which is more often used when cancelling a scope externally, e.g.
val myScope = CoroutineScope(Dispatchers.Main + Job())
// ...
override fun onDestroy() {
myScope.cancel()
}
dave08
01/02/2020, 4:51 PMcallbackFlow
...dave08
01/02/2020, 4:52 PMFlow
doesn't even have access to that scope anyways, so nobody's there to say "I can't receive things anymore" in that particular way.Adam Powell
01/02/2020, 4:53 PMCancellationException
. You immediately end up in cooperative cancellation limbo where isActive
is now false but your code in a cancelled job is still runningAdam Powell
01/02/2020, 5:30 PMtry {
myFlow.collect {
// ...
}
} catch (???) {
// ???
}
what do you want your flow's users to write in the ???
spots?Adam Powell
01/02/2020, 5:31 PMCancellationException
, check the cause
, then re-throw if it's a "real" coroutine cancellation vs. a reported error from your flow, you want them to be able to catch your exception typeAdam Powell
01/02/2020, 5:32 PMclose(e)
gives you thatAdam Powell
01/02/2020, 5:34 PMCancellationException
like that has major additional issues - you might have to unwrap several layers)dave08
01/02/2020, 5:38 PMcatch { }
operator... which probably gives that CancellationException
too with cancel
🤕... whereas with close
it would just give e
.
But you're saying with collect()
the close(e)
(even with the Exception
parameter), wouldn't throw a CancellationException
, it would just throw the e
itself...
This is also a good point, I guess that example in the repo is wrong...Adam Powell
01/02/2020, 5:41 PMAdam Powell
01/02/2020, 5:42 PM