Allan Wang
08/21/2019, 8:01 AMoctylFractal
08/21/2019, 8:02 AMcollect
, it will stop processingoctylFractal
08/21/2019, 8:03 AMcollect
, so you can't cancel it because that's equivalent to just not calling the terminal operation at all -- nothing is running yetAllan Wang
08/21/2019, 8:06 AMoctylFractal
08/21/2019, 8:08 AMisActive
, or yield()
louiscad
08/21/2019, 8:10 AMval myFlowCollectingCoroutine = launch {
someFlow.collect { // Or any terminal operator
// some cancellable code here
}
}
delay(someDurationOrSomeStuff)
myFlowCollectingCoroutine.cancel()
gildor
08/21/2019, 8:10 AMgildor
08/21/2019, 8:11 AMFlow.launchIn(scope)
operator which starts flow collection on new coroutine and returns Job that can be cancelled, but it’s essentially the same what Louis showed aboveAllan Wang
08/21/2019, 8:12 AMgildor
08/21/2019, 8:15 AMand have it all cancel once the activity (and the main job) is destroyedYou can do this, just use lifecycleScope to consume flow
gildor
08/21/2019, 8:16 AMsomeFlow.onEach {
doSomethingWith(it)
}.launchIn(activity.lifecycleScope)
gildor
08/21/2019, 8:16 AMgildor
08/21/2019, 8:17 AMoctylFractal
08/21/2019, 8:23 AMFlow
listen for cancellation somewhere? Otherwise, if doSomethingWith(it)
doesn't listen for cancellation, the flow would continue to execute, right?louiscad
08/21/2019, 8:25 AMcollect
and emit
are one of themoctylFractal
08/21/2019, 8:41 AMgildor
08/21/2019, 8:43 AMgildor
08/21/2019, 8:43 AMoctylFractal
08/21/2019, 8:44 AMisActive
check + return from collect
gildor
08/21/2019, 8:46 AMoctylFractal
08/21/2019, 8:47 AMoctylFractal
08/21/2019, 8:47 AMgildor
08/21/2019, 8:49 AMoctylFractal
08/21/2019, 8:49 AMdelay
is the cancelling part hereoctylFractal
08/21/2019, 8:49 AMThread.sleep
gildor
08/21/2019, 8:50 AMoctylFractal
08/21/2019, 8:51 AMemit
& collect
do not handle cancellation -- but the flow does exit properly if something else doesgildor
08/21/2019, 8:51 AMoctylFractal
08/21/2019, 8:53 AMgildor
08/21/2019, 8:54 AMoctylFractal
08/21/2019, 8:55 AMisActive
print false
if it's not cancelled?octylFractal
08/21/2019, 8:57 AMfalse
, indicating cancellation, but emit proceeds regardless: https://pl.kotl.in/w3xW51_Vblouiscad
08/21/2019, 9:03 AMemit
is cancellable 🤔louiscad
08/21/2019, 9:03 AMcollect
toogildor
08/21/2019, 9:04 AMoctylFractal
08/21/2019, 9:06 AMcollect
variant: https://pl.kotl.in/Fk7r6G-g1octylFractal
08/21/2019, 9:09 AMcollect
is cancellable here, or emit
in the other snippet, is that they don't behave like other cancellable functions. If `collect`/`emit` was cancellable, it shouldn't print that message. Here's what happens with delay: https://pl.kotl.in/UA0yi3erMgildor
08/21/2019, 9:15 AMoctylFractal
08/21/2019, 9:29 AMPablichjenkov
08/21/2019, 3:17 PMlouiscad
08/21/2019, 3:34 PMemit
by itself is non cancellable. collect
by itself it not cancellable either, but some operators built on top of it like collectLatest
might be.
Interestingly, the terminal toList()
operator doesn't seem cancellable as the following snippet executed in a coroutine scope that has just been cancelled prints `a, b`:
println(flow { emit("a"); emit("b") }.toList().joinToString())
This could leak to never cancelling coroutines if the flow is infite and no cancellable suspending functions are called, which would then leak resources.
Is this by design @elizarov?