perf(cmux-tui-core): a pane or tab list inside one workspace reads only that workspace (CLI-1)

Merged
LA
4d ago
+427-35

Summary

Under the L1 CLI storm against a 40-workspace / 200-terminal daemon (fleet run 360f44a009fb64208b8e3ab6, STATUS 6237), the largest holder of BOTH global daemon locks was public_session_snapshot (resource_api.rs:553): 22.2 s of registry hold and 22.2 s of Mux.state hold in a 60 s storm (37 %), 2,117 calls at about 10.5 ms each. Its callers were CLI tab list --pane P, pane list --workspace W and terminal list --pane P: each built the whole session snapshot (every workspace, screen, pane, tab, terminal, browser, notification, agent and frontend projection) and then kept one pane's rows. Idle, tab list and pane list grew from 6 ms at 1 workspace to 14 ms at 40; under the L6 app load (STATUS 6075) tab list was 50 ms p50 and every other daemon call waited behind these holds.

Fix: a pane.list or tab.list whose resolved path names a workspace (a --workspace, --screen or --pane scope) reads that workspace's stored subtree (resource_topology_scoped, the read the scoped projection already uses) under the registry lock only, not the state lock, and builds the same pane and tab values in the same order from one shared builder (public_pane_and_tab_values, now also used by the session snapshot), with the same tab decoration. A session-wide list keeps the snapshot.

Not in this PR: terminal.list --pane (a terminal value needs live runtime state; next PR), screen.list.

Owner: PL-daemon (cmux-tui daemon, cmux-tui/crates/cmux-tui-core/).

Changelog

none

Testing

Regression test: scoped_pane_and_tab_lists_read_only_their_workspace (cmux-tui-core, mux/tests/read_paths.rs). In a two-workspace session with a split and extra tabs, pane.list --workspace, tab.list --pane and tab.list --workspace must equal the session snapshot's rows for that scope, read no full topology, read no terminal host, projection or journal table, and write nothing.

  • Red at bf60e2d5f24 (test only): step 578ce041959f5ceafee6d050 FAILED as expected: pane.list {"workspace":...} read the whole topology (its value check passed on the base, so the expected rows are right).
  • Green and full cmux-tui suite at 6fd44a3044b: step aadb36b5a8e67ad9d51f110b: 15,151 of 15,154 passed, the new test among them. The 3 failures are the same base reds as on every head today, in files this PR does not touch (acpmux every_test_binary_runs_in_the_hermetic_environment and usage_stats::the_session_list_and_info_carry_what_the_chats_transcript_says, cmux-tui share_chat_waits_for_the_owners_answer).

Command: cmux-ci run --class isolated --script scripts/ci/cmux-tui-rust-check.sh --ref SHA --os linux --arg test --arg scoped_pane_and_tab_lists_read_only

A/B: interleaved before (23de9c20) / after (6fd44a30) runs of perf-10x-daemon.sh --arg=scenarios=cli-storm are queued on one mini (6c5c4e8f, 6633e96b against b4c6acd1, 1cc4271f); the numbers are added here when they end.

Observed / Not run

Observed: the base lock split (fleet run 360f44a0), the red and suite steps above.
Not run: an L6 round in the real app with this change.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes pane.list and tab.list calls scoped to a workspace, screen, or pane building the entire session snapshot and holding both global daemon locks. A scoped list now reads only that workspace's stored subtree under the registry lock alone, producing the same pane and tab values in the same order as before. Session-wide lists still read the snapshot; terminal.list and screen.list are unchanged.

Testing

  • Adds a regression test asserting scoped lists match the session snapshot's rows and read no full topology, terminal, projection, or journal tables.
  • Adds a cli-storm scenario to bench-daemon-latency.py that runs the L1 CLI mix against an L5-sized session and reports daemon lock and topology projection splits.