-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-conflating subscription count in MutableStateFlow and MutableSharedFlow #2871
Comments
…#2872) * Non-conflating subscription count in SharedFlow and StateFlow Sharing strategies are too sensitive to conflation around extrema and may miss the necessity to start or not to stop the sharing. For more particular examples see Kotlin#2863 and Kotlin#2488 Fixes Kotlin#2488 Fixes Kotlin#2863 Fixes Kotlin#2871
@qwwdfsad: the kdoc documentation of this change currently appears misleading (kotlinx.coroutines release 1.7.3):
This sounds as if the absence of conflation was not part of the contract for Rather, my reading of this issue here suggests that non-conflation is intended to be part of the contract. Otherwise a consumer of this API would not validly be able to rely on this behavior. |
Addresses the new comment to #2871
Problem statement
Currently, the infrastructure of
Flow
sharing is written with complete asynchrony and implementation unification in mind. While it benefits its usages in general, the implementation of sharing leaksStateFlow
conflation into seemingly orthogonal concepts such as sharing strategies.It can be demonstrated by the example from #2488:
The root cause is sharing implementation -- any sharing strategy subscribes to the flow
subscriptionCount
and observes the subscriptions. When the collector subscribes and immediately (whether in the same dispatcher or in a different one, but the one that is lagging behind) unsubscribed, the original value is conflated to zero.A more complex example that involves timings can be found in #2863.
Proposed solution
During the investigation, it was found that local changes cannot solve the asynchrony problem. While the targeted tweaks can address originally reported issues, the problem will be still unresolved and it will be possible to observe it in less trivial scenarios. It doesn't matter whether the sharing happens in the same thread (e.g.
Dispatchers.Main
) or in a separate one,the timings and conflations can still be observed in a way that breaks the mental model of sharing.
Due to compatibility reasons, it's close to impossible to change the type of
subscriptionCount
and it's not the goal to replace trivially-readable (subscriptionCount.value
) primitive with a brand new type.Instead, we decided to make
subscriptionCount
non-conflating -- any subscriber will be able to observe all changes in subscribers number. While it is not aligned with how the rest of the state flows behave, it is the smallest potentially-breaking change that only affects implementors of sharing strategies and introduces small inconsistency, but provides clear mental model to the library users and does not introduce new concepts to the libraryThe text was updated successfully, but these errors were encountered: