Jan Skrasek
07/30/2021, 10:10 PMMutableSharedFlow()
and Channel()
with runBlockingTest
I would expect both to behave the same; Yet when not using extraBufferaCapacity = 1, my following test fails for MutableSharedFlow and not for Channel. (See gist)
https://gist.github.com/hrach/94ba0dc427ad2f08a73467d8972516a2
• why is there a difference?
• is both behavior correct?
• is correct that there is a difference?Nick Allen
07/30/2021, 11:55 PMMutableSharedFlow
with no buffer space and SUSPEND
strategy. tryEmit
will always fail and return false.Nick Allen
07/30/2021, 11:59 PMMutableSharedFlow
replaces BroadcastChannel
, not Channel
. It can send events to many listeners, but it is not a queue.Nick Allen
07/31/2021, 12:01 AMJan Skrasek
07/31/2021, 5:52 AMYou are setting up yourwith no buffer space andMutableSharedFlow
strategy.SUSPEND
will always fail and return false.tryEmit
This seems to be crucial info. It could be in kdoc. Still I don't understand why channel with no buffer is able to handle this.
Nick Allen
07/31/2021, 6:19 PMFlow
uses a callback mechanism. When you call emit
on a FlowCollector
you wait for emit
to finish. If MutableSharedFlow
isn't allowed to store the value in a buffer, its emit
needs to loop through the listeners and wait for emit
to finish for each listener.Channel.send
waits for the data to be received, it does not wait for the data to be processed at all. It's more of a hand-off. send
doesn't need to suspend just to tell another coroutine to resume.Nick Allen
07/31/2021, 8:01 PMChannel
works because that's how it's designed to work.
MutableSharedFlow
could maybe work if its implementation changed, idk. Right now it just checks the buffer and buffer strategy to determine if tryEmit can work without suspending. This is nice because it's simple and fast. It could conceivably check if all listeners are "ready" but I imagine that could cause performance or just complexity issues.
I wouldn't say it's super clear, but the behavior does feel like it's documented in the kdocs here: "When this function returns false
, it means that the call to a plain emit function will suspend until there is a buffer space available."Jan Skrasek
07/31/2021, 9:21 PM