Repository navigation
Fix subject ordering during concurrent sends - #62
Merged
Merged
Conversation
Queue values and termination alongside subject state updates, then drain deliveries outside the state lock. Preserve a shared subscriber order and current-value/replay consistency without reintroducing cancellation-handler lock inversion. Add ordering, paused-drainer, and reentrant cancellation regressions for all six subjects. Document queued delivery timing.
4 of 5 tasks
3 of 5 tasks
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.
Description
Concurrent subject sends can reach subscribers in different orders, leaving current-value and replay subscribers on stale values. Serialize values and termination in a FIFO queue owned by each subject's existing locked state, then drain channel deliveries after releasing the lock. Apply the fix to all six subjects.
Closes #61.
The contributor's original delivery-lock proposal can deadlock when a consumer's cancellation handler sends back into the subject. The revised queue proposal avoids that cycle; this implementation also removes the separate queue lock by keeping queue admission, state updates, and subscriber snapshots in one critical region. Drainer ownership is released atomically with checking for an empty queue, preventing stranded deliveries.
Concurrent
sendcalls may return while another sender drains their queued delivery. State updates and subscriber registration remain synchronous. Document this timing in the README and changelog. Public signatures, dependencies, and deployment targets are unchanged. The internal queue's narrow@unchecked Sendableconformance documents the value-semantics invariant required by the pinned swift-collections 1.0.3 Deque, which lacks its own Sendable conformance.Validation
Validated on Apple Swift 6.4 / macOS against main at
93d173a, using an isolated copy containing exactly this change; all 12 committed files match the tested snapshot.swift build -Xswiftc -suppress-warnings: passed.swift test --enable-code-coverage -Xswiftc -suppress-warnings: 168 tests passed, zero failures.swift test --filter 'AsyncSubject(ConcurrentSendOrdering|QueuedDelivery|Cancellation)Tests': 24 tests passed, zero failures; no new compiler warnings, with 21 existing unused throwing-task warnings in older tests.git diff --check: passed.Checklist