-
Notifications
You must be signed in to change notification settings - Fork 782
Fix RefCount bugs #2216
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
Fix RefCount bugs #2216
Conversation
Disable inapplicable suggestion to use System.Threading.Lock. (Not available on .NET FX or .NET 8.)Disable inapplicable suggestion to use System.Threading.Lock (Not available on .NET FX or .NET 8.)
Clarify some test names Fix typo in comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes bugs in the RefCount operator, particularly addressing issues with state management when the subscriber count changes relative to the minObservers threshold. The fix includes two main bug corrections: preventing multiple reconnection attempts in the Eager implementation when minObservers > 1, and fixing SingleAssignmentDisposable exceptions in the Lazy implementation due to improper disconnect scheduling.
- Enhanced RefCount unit test coverage with comprehensive scenarios for both immediate and delayed disconnect modes
- Fixed Eager implementation to prevent reconnection when already connected
- Fixed Lazy implementation to properly handle delayed disconnects and prevent duplicate work items
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| azure-pipelines.rx.yml | Updates .NET target framework from 6.0/7.0 to 9.0 for CI pipeline |
| version.json | Bumps package version from 6.0.1-preview to 6.0.2-preview |
| MySubject.cs | Changes from single observer to list of observers to support multiple subscriptions in tests |
| RefCountTest.cs | Adds extensive test coverage for RefCount with new test helper classes and comprehensive scenarios |
| Tests.System.Reactive.csproj | Adds IDE0330 suppression for System.Threading.Lock warnings |
| RefCount.cs | Implements bug fixes for both Eager and Lazy RefCount implementations with state management improvements |
| Directory.build.props | Fixes TargetPlatformSdkPath resolution for UAP targets |
| WindowsDesktopTests.csproj | Updates target frameworks and package versions |
| LinuxTests.csproj | Updates target frameworks and package versions |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
* Fix crash when eager RefCount crosses min observer threshold more than once * Make RefCount tests more comprehensive * Fix RefCount with delayedDisconnect InvalidOperationException bugs Also fixed some build issues: * Fix missing TargetPlatformSdkPath (because an SDK change broke the build) * Bump version since we already released 6.0.1 * Update integration tests to use Rx 6.0.2 preview * Add release notes for 6.0.2
Resolves #2173, resolves #2214, resolves #2215
Adds more
RefCountunit tests.RefCounthas two implementations: theEagerone, which disconnects the instant the subscriber count drops to 0, and theLazyone, which is used by overloads ofRefCountthat specify adisconnectDelay, which disconnects only when the subscriber count has been at 0 for the duration specified. Both implementations had bugs.Broadly speaking, the problems were failures to distinguish between different states when hitting significant subscriber counts.
The
Eagerimplementation would crash ifminObserverswas greater than 1, and the subscriber count dropped below that threshold (but not to 0) and then back up to it. Each timeminObserverswas reached, it would reconnect, even if already connected.The
Lazyimplementation had a similar problem, but it occurred when the reference count hit zero: the operator would set up the work item to effect the delayed disconnect every time that happened, but if the count went to zero, then 1, then back to zero, this meant it would try to set up that callback twice. (This was not harmless, because it uses aSingleAssignmentDisposableto manage this, and it would throw anInvalidOperationExceptionthe second time it went to zero.) There was also a more subtle problem that occurred with sources that complete synchronously (i.e., they callOnCompletebefore returning fromSubscribe): it was possible for a delayed disconnect work item to get scheduled, and then for it not to get cancelled if a new subscriber arrived before the disconnect occurred. This could result in premature disconnection.