Skip to main content

Module cleanup

Module cleanup 

Source
Expand description

Periodic sweep that DELs abandoned sessions.

Two session kinds, two liveness rules:

  • WS shim sessions (client_id: Some): live while that client id is in the live Client store. When the client drops, a STALE_AFTER grace covers reconnect blips, then the session is DEL’d. Tracking is in-memory (disconnected_since); daemon restart resets it, giving every reloaded session a fresh grace window.

  • Pull/hook sessions (client_id: None): an HTTP-MCP agent that registered via the /hook/session-start endpoint has no WS client at all — it would be swept instantly by the client-id rule. Its liveness is instead its last_activity_at (the hook bumps it every turn) plus a long HOOK_BACKSTOP grace. The clean teardown path is the explicit /hook/session-end DEL; this grace is only a backstop for a client that crashed without firing SessionEnd. Because last_activity_at is wall-clock and persisted, the backstop survives daemon restarts.

Constants§

HOOK_BACKSTOP
How long a pull/hook session (no WS client) may go without any hook activity before the backstop DELs it. Generous: merely-idle sessions re-register on their next turn, so this only needs to be short enough to eventually reclaim sessions whose client crashed without firing /hook/session-end. 60 min.
MESSAGE_TTL
Messages older than this are pruned by sweep_messages, regardless of recipient. Direct messages already cascade away with a DEL’d recipient session; this bounds the ones that DON’T — broadcasts addressed to the never-DEL’d everyone/op:/project: rooms, which otherwise accumulate forever (review R6/D). DELing a Message cascades its MessageRead rows.
STALE_AFTER
How long a WS-shim session must be without a live client before DEL. Sized to survive a WHOLE-FLEET reconnect after a daemon restart: on restart every session replays from disk carrying a stale client_id, and the in-memory disconnected_since map is empty, so all sessions enter the grace at once. Too short and a slow-to-redial shim gets reaped — cascading its UNREAD direct messages away (belongs_to(Session), review R5) — before it reconnects to read them. 60s gives the fleet room to re-dial; a genuinely dead session just lingers that long (and the roster’s liveness fields show it going stale).
TICK_INTERVAL
How often the sweeper wakes up to check for stale sessions. Anything roughly under STALE_AFTER is fine; the trade-off is reaction latency (lower) vs. wake-ups per minute (higher).

Functions§

run_sweeper
Run the sweeper forever. Spawn this on a tokio task and forget it.