Repository navigation
Stop reading SSH output the webview has not caught up with - #159
Sadykhzadeh wants to merge 4 commits into
Conversation
PR Summary by QodoBound SSH output queued ahead of the webview
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
The reader handed every batch to the IPC channel without waiting, and large payloads sit in Tauri's in-memory queue until the webview fetches them, so a fast or hostile server could grow that queue without bound. Each SSH session now meters delivered output against a 2 MiB window of unacknowledged bytes. The webview acknowledges what it receives through session_output_ack, coalesced to every 256 KiB or 30 ms, and the reader stops polling the channel while the window is spent. russh hands channel data over through a bounded queue, so the stall reaches the server via the SSH window and TCP. Closing a session lifts the limit so the reader still reaches EOF, flushes the tail and announces the close.
The reader handed a batch to the UI layer and only then counted it against the window. An acknowledgement that overtook the spend would be clamped against nothing outstanding and lost, and enough of those would leave the window spent for good.
99900b3 to
b91ca46
Compare
The acknowledgement was dropped on failure. A reader that had used up its window then waited for credit that no further output would ever trigger, so one lost IPC call could freeze a busy session for good.
…wledgements for as long as the stream is open The previous commit picked up stale copies of sftp.rs and session.rs, which undid the close signal on single SFTP requests and moved the credit spend back behind the batch hand-off. A capped retry could also give up during a long outage and leave the session paused for good.
Closes #158. Stacked on #140 (
session.rs). Merge #140 first; this PR's base then becomesmain.What this changes
Core: a credit window per SSH session
OutputCredit(core/src/output.rs) counts bytes handed to the UI layer and not yet acknowledged, againstOUTPUT_WINDOW= 2 MiB.Notify::notify_one, which keeps a permit if the refund lands before the reader starts waiting.In the reader:
channel.wait()is polled only while there is room. Another branch waits for room otherwise.SshSession::retire, used byclose,close_alland the reader's own cleanup, lifts the limit. A reader stalled on credit therefore still reads to EOF, flushes the tail and announces the close, instead of waiting on acknowledgements that will never come.Backend command
session_output_ack(session_id, bytes)refunds credit. An id without a live SSH session is accepted and ignored: acknowledgements trail their output and can arrive after a close, and local terminals are not metered.Frontend
api.sessionOutput(sessionId, onData, onEnd)acknowledges batches as the webview receives them:TerminalPane.vueonly gains thesessionIdargument. The e2e fixture accepts the new command.Acks happen on receipt, not after xterm has rendered. What this bounds is the IPC queue, which is what the issue is about. xterm's own write buffer has its own cap.
Tests
OutputCreditunits. 7 unit tests inoutput.rs.core/tests/output_flow_control.rs. A loopback russh server floods 64 KiB chunks and the client never acks.acklets about one more window through.close()on a stalled session still announces the close, and late acks are ignored.desktop/src/api.sessionOutput.test.ts. 5 Vitest cases: coalescing, threshold, per-session ids, end of stream, and a failed ack being swallowed.Interaction with #123
#123 puts app commands behind the capability ACL. Whichever of the two merges second needs an
allow-session-output-ackentry inpermissions/app-commands.tomland in the capability.Test plan
cargo test -p clavyn-core: 125 unit + 5 + 32 + 1 + 4 + 9 integration, all pass (after rebasing on the current Keep the session maps unlocked across network I/O #140)cargo test -p clavyn-desktop(Linux, local): 107 + 2cd desktop && npx vue-tsc --noEmit: cleancd desktop && npm test: 46 files / 388 testscd desktop/e2e && UI_RECORD=0 npm test: 73 passednode scripts/verify/check-comments.mjs: oktauri devwith a slow webview: not exercised; throttling is tested at the core level and with mocked IPCNeed help on this PR? Tag
@codesmith-botwith what you need.