aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-13 00:34:10 +0200
committeruser <user@clank>2026-08-13 00:34:10 +0200
commit154ee360f6aff1178c52f4245595a4dec0eeba81 (patch)
tree383cc175f3dbc5a4ea002702bf85e2ac1296185e /docs
parentsl0p: stop recycling client ids, which silently ate CLI output (diff)
downloadsl0ppi-154ee360f6aff1178c52f4245595a4dec0eeba81.tar.gz
sl0ppi-154ee360f6aff1178c52f4245595a4dec0eeba81.tar.xz
sl0ppi-154ee360f6aff1178c52f4245595a4dec0eeba81.zip
docs: record the flakiness as fixed, with the measurements
Both causes are now understood and closed, so the known-issue section becomes a record of what it was and how it was proven fixed.
Diffstat (limited to 'docs')
-rw-r--r--docs/roadmap.md68
1 files changed, 27 insertions, 41 deletions
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 22fd270..6aa1059 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -127,52 +127,38 @@ Guard rails worth knowing:
---
-## Known issue: sl0ppij CLI actions are racy
+## Fixed: sl0ppij CLI actions were racy
-Measured on a 2-vCPU Debian box, against a **live** session:
+`zellij action` used to fail ~20-25% of the time against a live session on a
+2-vCPU box, and attached clients were dropped with "lost connection to the
+zellij server". Two independent causes, both now fixed and measured:
-| | detached | client attached |
-|---|---|---|
-| `action list-tabs --json` | ~60% fail | ~25% fail |
-| `action list-panes --json` | ~60% fail | ~25% fail |
-
-Failures are either an empty stdout with exit 0, or `There is no active
-session!`. The action client calls `get_active_session()` before it consults
-`-s`, so a transient enumeration failure looks like "no session at all".
-
-The CLI works around it (idempotent reads are retried with backoff, which took
-`sl0ppi ls` from failing most runs to 8/8), but the fork should be fixed: any
-consumer of `zellij action` on a slow machine will hit this, and most will
-conclude their session is dead.
-
-**Partly fixed in `sl0p: stop suspended panes spamming resize errors`.** Half of
-it was self-inflicted: every resize logged one error per `start_suspended` pane
-on the server's hot path, and sl0ppi puts a suspended agent in every project. On
-the same box that took `list-tabs` against a two-suspended-pane session from
-5/12 failing to 6/30, with the error storm gone entirely (126+ -> 0).
+1. **Client ids were recycled instantly** (`sl0p: stop recycling client ids`).
+ Every action probes liveness first (`assert_socket` connects, sends
+ `ConnStatus`, disconnects), and that probe is a full client. `new_client()`
+ returned the lowest free id, so the action connection got the probe's id
+ back; the queued `ConnStatus` removal then deleted the *action* client, and
+ its reply was dropped by `send_to_client`, which returns `Ok(())` for an
+ unknown id. Result: exit 0, no output, nothing logged.
-**The remaining ~25% is a real IPC bug, and it is now located.** Every
-`zellij action` calls `sessions.rs::assert_socket()`, which connects to the
-session socket, sends `ConnStatus`, and waits for exactly `Connected`:
+2. **Suspended panes spammed resize errors** (`sl0p: stop suspended panes
+ spamming resize errors`). A reserved-but-unstarted terminal has no fd, which
+ was treated as an error and logged per pane per resize, on the server's hot
+ path. sl0ppi puts a suspended agent in every project, so it was the heaviest
+ possible user of that path.
-```rust
-match receiver.recv_server_msg() {
- Some((ServerToClientMsg::Connected, _)) => true,
- None | Some((_, _)) => false, // <- anything else means "dead"
-}
-```
-
-So a server that is momentarily busy, or that happens to send a different
-message first, is reported as **no session at all** -- which is why the failure
-surfaces as "There is no active session!" against a session that is demonstrably
-alive. Worse, the `ConnectionRefused` arm above it `remove_file`s the socket, so
-a transient refusal can delete a live session's socket.
+| | before | after |
+|---|---|---|
+| `list-tabs` | ~20-25% fail | **0/50** |
+| `list-panes` | ~20-25% fail | **0/50** |
+| `list-tabs`, client attached | ~25% fail | **0/30** |
+| `sl0ppi ls` | failed most runs | **0/15** |
+| 5 attach cycles | dropped | **5/5 stable** |
+| resize errors logged | 126+ | **0** |
-Proposed fix (not yet made, because it changes the client/server handshake and
-deserves its own session): read messages for a short bounded window looking for
-`Connected` rather than judging on the first one, and do not delete a socket on
-a single refusal. The attach-time "lost connection to the server" drop is a
-different path (the client's receive loop) and needs separate measurement.
+Worth revisiting: `send_to_client` silently returns `Ok(())` for an unknown
+client id. An unknown id is a caller bug, and swallowing it is what made this
+take a day to find instead of a minute.
## Standing risks