diff options
| author | user <user@clank> | 2026-08-13 00:33:31 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-13 00:33:31 +0200 |
| commit | abd7355104e85360fdb62fc8f9560522fff0c028 (patch) | |
| tree | 0df671a7ab00a3ef6446afde973900036bfb4b6d /cli/src | |
| parent | docs: locate the remaining action flakiness in assert_socket (diff) | |
| download | sl0ppi-abd7355104e85360fdb62fc8f9560522fff0c028.tar.gz sl0ppi-abd7355104e85360fdb62fc8f9560522fff0c028.tar.xz sl0ppi-abd7355104e85360fdb62fc8f9560522fff0c028.zip | |
sl0p: stop recycling client ids, which silently ate CLI output
`zellij action` failed ~20% of the time against a live session: exit 0, empty
stdout, empty stderr, and nothing in the server log. `sl0ppi ls` inherited it,
and attached clients were dropped with "lost connection to the zellij server".
The chain, which took measuring rather than reading to find:
1. every action first probes liveness (sessions::assert_socket): connect,
send ConnStatus, disconnect. The probe is a full client and takes an id.
2. new_client() handed out the LOWEST FREE id, so the action connection that
follows microseconds later gets the id the probe just released.
3. the main server thread then processes the queued ConnStatus(id), whose
handler replies and calls remove_client!(id) -- removing the *action*
client, which now owns that id.
4. the action's reply goes through send_to_client, which returns Ok(()) for an
unknown client. The payload is dropped in silence; the client sees only the
disconnect and exits 0 with nothing to print.
Fix: hand out ids from an advancing cursor instead of reusing the lowest free
one, so a stale removal cannot land on a fresh connection. ClientId is a u16 and
every CLI invocation burns two, so the cursor wraps and skips ids that are still
in use rather than assuming they are free.
Measured on the 2-vCPU Debian box that surfaced this:
before after
list-tabs ~20-25% 0/50 failed
list-panes ~20-25% 0/50 failed
list-tabs (attached) ~25% 0/30 failed
sl0ppi ls most runs 0/15 failed
5 attach cycles dropped 5/5 stable
Three regression tests: ids are not reused immediately, they advance and skip
live ones, and they wrap without colliding or hanging. zellij-server: 1502 pass.
The silent-drop in send_to_client is left as-is but is worth revisiting: an
unknown client id is a bug in the caller, and swallowing it is what made this
cost a day instead of a minute.
Diffstat (limited to 'cli/src')
0 files changed, 0 insertions, 0 deletions
