-
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
StateFlow with SharingStarted.Lazily parameter does not start background coroutine in specific cases #2488
Comments
The root cause is that |
Our documentation for Now consider a simplified reproducer without flaky timings:
This code will fail, |
Agreed. I'll fix it. |
Having investigated it I don't see a way to fix it. The underlying reason of this behavior is that |
Couldn't be this workarounded by providing other initial value (like -1) so that change to 0 would trigger the lazily started sharing? |
There are some other hacks that can be made to make it work specifically for the case of |
I, as a library user, would definitely want to have the best performance and expected behavior for the
I see 3 solutions for this problem:
I would personally strive for the ideal solution by providing extensive API and expected behavior (1) but if it is not possible for some reason (e.g. performance downgrade), I would eliminate any controversial API that can lead to unexpected behavior (2), especially if it can be replaced safely with similar code. |
Another solution is to make the number of subscriptions a |
…#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
Consider the following test:
The reference for the
SharingStarted.Lazily
says: "Sharing is started when the first subscriber appears and never stops".When
flow1.first()
statement is executed, based on the reference, it is expected thatflow1
stream starts on the background and never stops.The test above shows that the actual behavior differs from the expected: second call of
flow1.first()
statement sends0
value but it shouldn't becauseflow0
has already populatedflow1
state with new values.It happens, perhaps, because
first()
operator gets the default value and cancels subscription fromflow1
stream before it subscribes toflow0
. In some cases the test above is passed.Another example that can reproduce race condition:
Kotlin: 1.4.21
Coroutines: 1.4.2
Runtime: JVM
The text was updated successfully, but these errors were encountered: