mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
fix(remote): bound the history read's slot wait in the queue, back off only on transport failures
Review follow-ups for the remote scrollback read. The 1.5 s slot-wait bound was checked inside the task, so it only fired once runWithRemoteSshLimit() had already handed over a slot, after everything queued ahead of it. runWithRemoteSshLimit() now takes `maxWaitMs`: a waiter that times out leaves the queue, rejects with RemoteSshSlotTimeoutError, never runs and never touches `active`. The history read uses it, and a slot timeout does not back the host off. Only a transport failure backs the host off now (ssh exit 255, a timeout, a spawn error, output that is not the script's), via classifyRemoteAliveExit(). A remote command failing is about that session only. A live run against a real host showed a missing session comes back as exit 0 with empty markers, because the `| tail -c` pipe takes tail's exit status, so markers that arrived without a size are also per-session. fetchRemoteScrollback() takes an optional runner as a test seam; tests now cover the bounded wait, each back-off class, its expiry, and the masked missing-session case. A source pin covers the `-S 0` capture branch. The two seams that can drop rows at the join (rows that scroll during the round trip, a taller shared client) are documented in docs/remote-sessions.md, and the limiter's header and the remote-ssh invariants now name the history read as an ssh consumer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b33d6da58a
commit
136f11549b
7 files changed
+304
-42
No files matched your search
+20
-4
@@ -258,10 +258,26 @@ full-screen repaints and keeps a fraction of the scrollback (none after a
|
||||
reattach). A full-history load (`GET /api/sessions/:id/terminal?full=1`) of a
|
||||
remote session therefore reads the scrollback rows from the REMOTE pane in one
|
||||
ssh round trip (`src/remote-pane-history.ts`) and splices them above the local
|
||||
visible frame and caret. Bounded (5 s, the shared ssh limiter) and fail-soft:
|
||||
any failure keeps the local capture and skips that host for 30 s. How much
|
||||
history exists is the remote tmux's own `history-limit`, which the launch
|
||||
command does not set (tmux's default is 2000 lines).
|
||||
visible frame and caret. Bounded (5 s for the round trip, at most 1.5 s queued
|
||||
for a slot in the shared ssh limiter) and fail-soft: any failure keeps the
|
||||
local capture, and a transport failure (ssh exit 255, a timeout, output that is
|
||||
not the script's) also skips that host for 30 s; a failure of the remote
|
||||
command itself (a remote tmux session that is gone) affects that session only.
|
||||
How much history exists is the remote tmux's own `history-limit`, which the
|
||||
launch command does not set (tmux's default is 2000 lines).
|
||||
|
||||
Two seams can drop rows at the join, silently. Neither loses anything that
|
||||
loaded before this existed:
|
||||
|
||||
- **Rows that scroll during the round trip.** The remote history is read
|
||||
first and the local frame after it, so rows that scrolled off the remote
|
||||
screen in between are in neither (measured: 13 lines lost with a 150 ms
|
||||
round trip and fast output).
|
||||
- **A shared remote session with a taller client.** Under `window-size latest`
|
||||
a remote session attached elsewhere is sized by its latest client; when that
|
||||
client is taller than this pane, the rows between this pane's frame and the
|
||||
remote screen's top are in neither the remote history nor the local frame
|
||||
(measured: 20 rows).
|
||||
|
||||
## File access over SSH
|
||||
|
||||
|
||||
Reference in new issue
Block a user