Repository navigation
Typing under load (F4 follow-up B): a key takes no session lock when a workspace has a size default - #32255
Merged
Conversation
…he session lock (TYPING FIX 2, #31940 follow-up A) The terminal kept for the person's keys (#31940) is checked against one process-wide route generation that every routing write moves. A tab create or close in any workspace (an agent's tab storm) therefore sent every attached client's next key back to the session lock: O(clients) lock takes per routing change, during the very load the lane exists for. The test counts the session lock acquisitions of the key's turn on its own thread (a test-only counter in StateMutex), so it needs no timing: after a new workspace, a tab in it and that tab's close, the next key must take the lock 0 times. Red at this commit: it takes it once.
…nges (TYPING FIX 2, #31940 follow-up A) #31940 checked the terminal kept for the person's keys against one process-wide route generation that every routing write moved. Every tab create or close anywhere (an agent's tab storm, a CLI new-workspace) therefore sent every attached client's next key back to the session lock: O(clients) lock takes per change, under the load the lane is for. Now each surface id has its own route generation (a fixed array of 1024 slots, id % 1024: bounded memory, nothing to remove, lock-free reads). A RouteTable write moves only the ids whose route it changes (RouteKey): a surfaces or terminal_catalog_by_runtime write its key, a terminal_catalog write the runtime ids of the owner it removes and the owner it puts in. terminal_catalog_by_runtime is a RouteTable now too, so every table an id routes through moves that id. Two ids in one slot only make a key look its terminal up once more, never use a stale one. The respawn, rollback and mutation tests of #31940 keep their meaning.
…n lock (TYPING FIX 2, #31940 follow-up B) Each key notes its view's activity in the sizing engine. That mutation re-expanded the host policy, which asks whether the terminal follows a workspace default (workspace_default_of), which looks the terminal's workspace up under the session lock, and may walk every surface for its placements, as soon as any workspace has a size default. So with a workspace default every key took the session lock again. Red at this commit: with the settings owner's host policy and a default on the typing terminal's workspace, the second key takes the lock once.
…FIX 2, #31940 follow-up B) Every sizing mutation re-expanded the host policy for its terminal, because participants may have come, gone or changed identity. A key's activity note changes none of them, and the expansion depends on nothing else a key changes. But the refresh first asks whether the terminal follows a workspace default (workspace_default_of), which looks the terminal's workspace up under the session lock and may walk every surface for its placements; with any workspace size default set, every key took the session lock again, behind automation. Activity now goes through mutate_terminal_sizing_keeping_participants, which is mutate_terminal_sizing without that refresh. Every mutation that adds, removes or renames a participant still refreshes it, and a workspace default, terminal override or host policy change still re-applies to the terminals it covers.
Contributor
Author
|
Review (claude-subagent, correctness first): SHIP at 589a571 What I checked (code reading only, no local build or test):
Non-blocking notes:
|
Base automatically changed from
perf/typing-fix-2-scoped-route
to
feat-cmux-next
November 2, 2026 13:07
…-fix-2-size-default # Conflicts: # cmux-tui/crates/cmux-tui-core/src/server/tests/input_lane.rs
lawrencecchen
temporarily deployed
to
ci-routing-agent
November 2, 2026 13:47 — with
GitHub Actions
Inactive
Contributor
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
Contributor
Author
|
Review (claude-subagent, correctness first): SHIP at 24cb4f6 Re-check after the merge of origin/feat-cmux-next (627d40b). I read the code only and did not build.
The non-blocking notes of my first review are unchanged. |
lawrencecchen
temporarily deployed
to
sentry-dsyms
November 2, 2026 13:57 — with
GitHub Actions
Inactive
lawrencecchen
temporarily deployed
to
artifacts
November 2, 2026 13:57 — with
GitHub Actions
Inactive
lawrencecchen
temporarily deployed
to
artifacts
November 2, 2026 14:00 — with
GitHub Actions
Inactive
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up B of #31940 (TYPING UNDER LOAD F4). Stacked on #32249 (base branch
perf/typing-fix-2-scoped-route; it retargets tofeat-cmux-nextwhen #32249 lands). Only the last two commits are this PR.Each key notes its view's activity in the terminal sizing engine (
note_terminal_activity_of). That mutation went throughmutate_terminal_sizing, which always re-expands the host size policy, because a mutation may add, remove or rename a participant. The re-expansion first asks whether the terminal follows a workspace default (follows_host_policy->workspace_default_of), which looks the terminal's workspace up under the session lock, and may walk every surface for its placements (runtime_placements). So as soon as any workspace had a size default, every key took the session lock again, behind automation.A key's activity changes no participant and no identity, and the host policy's expansion depends only on those. Activity now goes through
mutate_terminal_sizing_keeping_participants: the same mutation, grid apply and publications, without the host policy refresh. Every mutation that adds, removes or renames a participant still refreshes it. A workspace default, terminal override or host policy change still re-applies to the terminals it covers (set_workspace_size_policy,adopt_host_size_policy).Testing
Regression test (cmux-tui-core
server::tests::input_lane):a_workspace_size_default_keeps_the_key_off_the_session_lock. With the settings owner's host policy and a size default on the typing terminal's workspace, the second key of an attached client must take the session lock 0 times (a lock-take counter on the key's thread; no timing).Command:
cmux-ci run --class isolated --os linux --script scripts/ci/cmux-tui-rust-check.sh --arg test --arg input_lane --ref <sha>left: 1, right: 0): steps 69cc2ac5fb3ef248808816da, f4f3e7ff6e6a5bec4159ddd2, 841b858ce4ef613a6267a6f1, 8a215f32c596cd120a66b7ea, e95e360d3d9e98db3637b2d7.test sizing): 57 of 57 pass (step 38481cb32fc72fbca15efed9), includinghost_size_policy(latest follows input, a workspace default of any placement, policy revisions).Review note (non-blocking, from the SHIP review): a key no longer re-resolves the host policy, so a tab moved out of a workspace with a size default gets the host policy back at its next attach, report, detach or focus click, not at its next key. A move into a workspace with a default was never re-resolved; a follow-up can re-resolve the policy on a move.
Observed / Not run
test server::1461/1461 (step c21e70d1f9d776d4ad85ddf5);test respawn87/87 (994538d1b982db7769e2dcf9);test terminal_catalog3/3 (b4047657d9e90c8fa112b8ea);test mux::535/535 after one retry (acb7928c7b4dafd4b4a3a669:mux::tests::history_agent_fold::agent_history_save_does_not_wait_for_the_workspace_registry_lockfailed once and passed on its retry; not in the changed code); panic ratchet passes (8d9e9cf6fa331c690908a2e6). clippy (34db00e016d830bcf7b85dbb) fails only inmux/tests/read_paths.rsfrom perf(cmux-tui-core): a pane or tab list inside one workspace reads only that workspace (CLI-1) #32177, a base finding on feat (not in this stack).Changelog
Fixed: Typing in a terminal no longer waits behind scripts and agents when a workspace has a terminal size default
Proof
No capture: daemon-only change, no UI.