Bug
AsyncStream.init(register:unregister:initialValue:) (Sources/SundialKitStream/AsyncStream+Continuation.swift) registers the continuation and yields the initial snapshot inside an unstructured Task:
register(id, cont) completes — the continuation is now live and receives manager yields.
initialValue() is awaited, reads current state, and yields it.
Between steps 1 and 2 (or between the state read and the yield), a live update can be yielded by the state manager. The stale initial snapshot then arrives after the newer live value, so a subscriber's last-seen value is wrong — e.g. reachabilityUpdates() can end on isReachable=false while the session is actually reachable.
Observed downstream in brightdigit/AtLeast as a candidate cause of "phone shows watch unreachable while the watch app is active" (see brightdigit/AtLeast — STARTING_ON_WATCH_BUG.md).
Fix direction
Make registration and the current-value yield atomic inside StreamContinuationManager (e.g. registerReachability(id:continuation:) yields the current value before returning, within actor isolation), and drop the separate initialValue closure.
Bug
AsyncStream.init(register:unregister:initialValue:)(Sources/SundialKitStream/AsyncStream+Continuation.swift) registers the continuation and yields the initial snapshot inside an unstructuredTask:register(id, cont)completes — the continuation is now live and receives manager yields.initialValue()is awaited, reads current state, and yields it.Between steps 1 and 2 (or between the state read and the yield), a live update can be yielded by the state manager. The stale initial snapshot then arrives after the newer live value, so a subscriber's last-seen value is wrong — e.g.
reachabilityUpdates()can end onisReachable=falsewhile the session is actually reachable.Observed downstream in brightdigit/AtLeast as a candidate cause of "phone shows watch unreachable while the watch app is active" (see brightdigit/AtLeast — STARTING_ON_WATCH_BUG.md).
Fix direction
Make registration and the current-value yield atomic inside
StreamContinuationManager(e.g.registerReachability(id:continuation:)yields the current value before returning, within actor isolation), and drop the separateinitialValueclosure.