ADR-0037: Stale-link detection at the protocol layer
- Status: Accepted
- Date: 2026-07-12
- Deciders: jka
- Decision: D37
Context
A GUI attached to a remote core through an ssh -L tunnel lost the tunnel. The
socket stayed half-open: writes succeeded into the kernel buffer, but no replies
and no end-of-file arrived. Clicks did nothing, and only after five to ten minutes
did TCP give up. The question was whether rio could notice sooner without adding
socket options, keepalives or platform-specific code.
Decision
The GUI runs a watchdog built from pieces the protocol already had: the bounded call
timer, session.hello as a ping, and the existing teardown path. Every 10 seconds
it checks:
- An overdue reply: a call pending longer than 25 seconds. No rio operation legitimately holds its reply open, because streaming operations acknowledge immediately and continue with events (ADR-0011).
- An idle probe: if nothing is pending and nothing has arrived for a full
interval, one
session.hellobounded at 8 seconds. Any received line, including streaming events, counts as life.
Either finding tears down the connection with a message that names the likely cause and the remedy: re-establish the tunnel, then File ▸ Connect to Remote Core… with the last endpoint prefilled.
The watchdog is armed only for socket connections. A pipe to a spawned core delivers end-of-file as soon as the child exits, so the half-open case cannot occur there. rio does not reconnect automatically.
Consequences
- A stale link is reported within about 35 seconds when idle and about 25 seconds after a click.
- The thresholds are plain variables, so tests can shrink them.
- Automatic reconnection is left out because the tunnel must return first, and silently re-attaching raises questions about unsaved buffers that the explicit reconnect already handles with the user present.
- The watchdog is keyed on "socket transport". While a socket is the only remote transport, the GUI's single "remote core" flag can stand for both "socket" and "not my filesystem". Anything that makes a pipe remote must split the flag first (ADR-0096).