Commit Graph

2 Commits

Author SHA1 Message Date
Joseph Doherty 0c9e4f4e3d fix(client): a failover abandons itself once the user disconnects or reconnects; paging and teardown minors
Review I1: ConnectAsync, DisconnectAsync and Dispose each start a new connection
epoch under _subscriptionLock. A keep-alive failover runs under the epoch it
started in and abandons itself the moment it moves: it installs its session only
if the epoch still matches (checked and assigned under the lock, otherwise the
session is disposed), its state transitions are epoch-guarded, it stops trying
endpoints, and it never flips a user's new connection to Disconnected. A late
keep-alive from a previous connection's session starts no failover. Gate-driven
tests cover the success and all-fail arms, the stale keep-alive, with a genuine
failover as the positive control (4 of them red before).

Minors: m8 only the CompareExchange winner sets LastFailover; m5 the endpoint
loop stops early, and a failed Unsubscribe still drops its bookkeeping; m1 a read
cancelled mid-paging releases its cursor (bounded token) and rethrows, and the cap
release no longer rides the caller's token; m2 results are trimmed to the cap;
m3 a non-positive cap is refused (CLI and UI already bound it to >= 1); m6 the
subscription adapter's Dispose uses one bounded bridge for delete + detach.

Refs #747
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 17:18:26 -04:00
Joseph Doherty 57ae69a05e fix(client): release a capped HistoryRead cursor, read (not release) follow-up pages, detach deleted subscriptions
R08 1.4: raw and modified history reads share HistoryReadPaging. A read stopped by
the caller's cap releases the server continuation point. The raw path also passed
releaseContinuationPoints = (cp != null), which released page two instead of reading
it, so every raw read was silently truncated to its first server page.

R08 1.5: DefaultSubscriptionAdapter removes its Subscription from the SDK Session
on delete/dispose (and a failed CreateAsync removes it too), so re-targeted alarm
subscriptions no longer accumulate in Session.Subscriptions.

Refs #747
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 16:21:22 -04:00