fix(agent): compare-and-clear session teardown on connection generation #99

Merged
Claude-Run merged 1 commit from feat/VS-81-connection-generation-compare-and-clear into main 2026-07-02 04:39:55 +02:00
Member

Overlapping agent connections for one node_id let a stale connection's teardown clobber the live one. handle_session keyed connectivity, the outbound sender, and disconnect notify by node_id alone, and the post-loop cleanup cleared them unconditionally. When a host reconnected while the server still held a half-open prior socket, connection B overwrote A's sender via set_sender; when A's dead socket was finally detected, A's cleanup cleared the bit and sender that now belonged to B, so the device showed offline and outbound commands silently dropped while the agent was live on B.

Give each connection a monotonic generation owned by AgentRegistry. set_sender stamps a fresh generation (from a global AtomicU64) and returns it; teardown calls clear_sender_if_current(node_id, generation), which clears the sender and self-update slot only when the stored generation still matches. A stale, superseded connection's generation no longer matches, so its teardown is a no-op. agent.rs gates the connectivity-bit clear and the agentdisconnect/power-off logging on that result, so a stale teardown never marks a live device offline.

VS-80's read-idle deadline turns half-open sockets over faster and makes this overlap more likely, so this lands alongside it.

#VS-81

Overlapping agent connections for one node_id let a stale connection's teardown clobber the live one. `handle_session` keyed connectivity, the outbound sender, and disconnect notify by `node_id` alone, and the post-loop cleanup cleared them unconditionally. When a host reconnected while the server still held a half-open prior socket, connection B overwrote A's sender via `set_sender`; when A's dead socket was finally detected, A's cleanup cleared the bit and sender that now belonged to B, so the device showed offline and outbound commands silently dropped while the agent was live on B. Give each connection a monotonic generation owned by `AgentRegistry`. `set_sender` stamps a fresh generation (from a global `AtomicU64`) and returns it; teardown calls `clear_sender_if_current(node_id, generation)`, which clears the sender and self-update slot only when the stored generation still matches. A stale, superseded connection's generation no longer matches, so its teardown is a no-op. `agent.rs` gates the connectivity-bit clear and the agentdisconnect/power-off logging on that result, so a stale teardown never marks a live device offline. VS-80's read-idle deadline turns half-open sockets over faster and makes this overlap more likely, so this lands alongside it. #VS-81
fix(agent): compare-and-clear session teardown on connection generation
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 2m1s
Create release / Create release from merged PR (pull_request) Has been skipped
975d616095
Overlapping agent connections for one node_id let a stale connection's teardown clobber the live one. `handle_session` keyed connectivity, the outbound sender, and disconnect notify by `node_id` alone, and the post-loop cleanup cleared them unconditionally. When a host reconnected while the server still held a half-open prior socket, connection B overwrote A's sender via `set_sender`; when A's dead socket was finally detected, A's cleanup cleared the bit and sender that now belonged to B, so the device showed offline and outbound commands silently dropped while the agent was live on B.

Give each connection a monotonic generation owned by `AgentRegistry`. `set_sender` stamps a fresh generation (from a global `AtomicU64`) and returns it; teardown calls `clear_sender_if_current(node_id, generation)`, which clears the sender and self-update slot only when the stored generation still matches. A stale, superseded connection's generation no longer matches, so its teardown is a no-op. `agent.rs` gates the connectivity-bit clear and the agentdisconnect/power-off logging on that result, so a stale teardown never marks a live device offline.

VS-80's read-idle deadline turns half-open sockets over faster and makes this overlap more likely, so this lands alongside it.

#VS-81
Claude-Run deleted branch feat/VS-81-connection-generation-compare-and-clear 2026-07-02 04:39:55 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-server!99
No description provided.