Skip to content

[Bug]: Switch can overlap exclusive subscriptions and discard a reentrantly selected source #1179

Description

@dwcullop

Please note we can't commit to any timeline.

Describe the bug 🐞

The cache Switch operator assigns the result of SubscribeSafe to its SerialDisposable after subscription has already begun. A replacement can try to acquire a resource still held by the previous subscription. Synchronous initial delivery, reset delivery, or disposal can also select a newer source, after which the older selection starts or overwrites the current subscription. The latest source is disconnected and its updates are lost.

Step to reproduce

Select a cold changeset source that owns an exclusive resource, then select it again. Separately, select a source with a synchronous initial Add and select another source from the downstream callback. Both are supported single-threaded scenarios.

Regression tests/checks:

ReplacementReleasesPreviousSubscriptionBeforeAcquiringResource; ReentrantSelectionDuringSynchronousAddKeepsLatestSubscription; ReentrantSelectionDuringResetDoesNotSubscribeSupersededReplacement; ReentrantSelectionDuringDisposalDoesNotSubscribeSupersededReplacement; DisposalDuringResetDoesNotSubscribeReplacement; OuterErrorDuringResetDoesNotSubscribeReplacement

Reproduction repository

https://github.com/reactivemarbles/DynamicData/tree/85ee49cfd54d8782c36ed137886d318e942345c4

Regression tests and fixes:
https://github.com/reactivemarbles/DynamicData/tree/u/dacullop/main/pr-1165-review

Expected behavior

The old subscription must be released before its replacement starts. A superseded or canceled selection must not subscribe, and a late returning subscription must not replace the newest selection.

Screenshots 🖼️

N/A.

IDE

N/A; command-line reproduction.

Operating system

Windows.

Version

.NET SDK 10.0.401; net9.0 test target.

Device

N/A.

DynamicData Version

Main 10.0-preview at 85ee49c. The related 9.5 candidate is PR #1165 at 3d76872.

Additional information ℹ️

Repository tests fail with an exclusive-resource InvalidOperationException, latestRemainedSubscribed=false, or a canceled replacement subscription count of 1 rather than 0.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions