Fix ReplaySubject race condition#138
Merged
freak4pc merged 1 commit intoCombineCommunity:mainfrom Jul 23, 2022
Merged
Conversation
…e locked to ensure new values are sent after the replayed values.
Codecov Report
@@ Coverage Diff @@
## main #138 +/- ##
==========================================
+ Coverage 95.53% 95.55% +0.02%
==========================================
Files 68 68
Lines 3833 3851 +18
==========================================
+ Hits 3662 3680 +18
Misses 171 171
Continue to review full report at Codecov.
|
freak4pc
approved these changes
Jul 23, 2022
Member
freak4pc
left a comment
There was a problem hiding this comment.
Very interesting. Thanks for the fix :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The ReplaySubject currently adds a new subscription before replaying the buffer. Since these two steps are not synchronized by the lock, it is possible that a new value is sent to the new subscription before the new subscription finishes replaying the buffer. This can result in a new subscription to a ReplaySubject receiving values out of order.
To fix this, it should be safe to have the new subscription replay the buffer before being added to the collection of subscriptions. The new subscription's DemandBuffer will have no requested demand at this point, so it will hold onto the replayed values until demand is requested. Once the lock is unlocked, any new values will be sent to all the subscriptions, which will always be added to the demand buffer after the replayed values.
I tried to keep the footprint of the new test minimal, but let me know if additional comments or helper methods could make it more clear.