Make subject termination permanent and fix zero-capacity replay - #69
Merged
Merged
Conversation
Ignore later values and terminal signals across all six subjects, preserve the first outcome for late consumers, and freeze stored state. Cover repeated and concurrent termination, paused delivery, and ignored-value lifetime; document the complete subject regression contract.
Retain no replay history when capacity is zero while delivering live values to existing subscribers. Cover late subscription and payload release for both replay variants and document the capacity contract.
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
Repeated termination can give existing and late subject subscribers different outcomes. Values sent after termination can also change a current-value subject or repopulate cleared replay history, and replay capacity zero currently retains one historical value.
Make the first finish or failure permanent across all six subjects and ignore later values, current-value assignments, and termination signals. Keep the last accepted current value and cleared replay history. Both replay variants now retain no history at capacity zero while delivering every live value to existing subscribers.
Preserve atomic registration and FIFO delivery outside the subject lock. Concurrent sends can still return while another sender drains their delivery; channel delivery does not wait for application code to process the value. Document these contracts and map each subject guarantee to its regression coverage.
Related: the guarantee audit in issue #61.
The commits separate permanent termination from zero-capacity replay. No public signatures, dependency requirements, deployment targets, channel implementations, or delivery-queue mechanisms change.
Validation
Validated on Apple Swift 6.4 / macOS. The committed content matches the tested snapshot exactly.
swift build -Xswiftc -suppress-warnings: passed.swift test --filter 'Async.*Subject.*Tests' -Xswiftc -suppress-warnings: 81 tests passed, including registration, cancellation, ordering, queued delivery, termination, and lifetime coverage.swift test --enable-code-coverage -Xswiftc -suppress-warnings: all 199 tests passed, zero failures.git diff origin/main..HEAD --check: passed.A Swift 5.8 toolchain was unavailable locally; minimum-toolchain validation was not run.
Checklist