Repository navigation
cmux-tui: a sidebar group collapse answers while busy sessions hold the registry - #34565
Conversation
|
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)
red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: Shipped in:
|
|
Found 6 test failures on Blacksmith runners: Failures
|
|
Owned by an agent session · session |
|
Review (codex gpt-6.1-sol xhigh, router-review range 427dd19..3e02bae in deltas): SHIP at 3e02bae
Visual verdict: unchanged by this diff (no UI code). |
…y session writers Rebased onto feat-cmux-next 0a2b815; same tree as merge 93200c84. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3e02bae to
c9c6c68
Compare
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Review (codex gpt-6.1-sol xhigh, router-review): SHIP at c9c6c68 Range 0a2b815..c9c6c68 (the PR rebased onto base; same tree as the conflict resolution of 3e02bae). Checked lock handoffs, scope lifetimes and request paths; no findings. Tests at this head: fast-checks run 41786996208, Follow-ups: none |
|
The test this PR added, (BASE RED SUITE for the cmux-next Performance Lead.) |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo, on the sidebar: "what's up with this ? im just clicking the expand/collapse situation in the workspaces is kinda awk" / "as in im doing it but it sends this message for no reason". The notice read: "Collapse/Expand Workspace Group did not apply: update-personal-group: timed out: workspace_group.update (no reply within 2.0 seconds)".
workspace.placeandnew-conversation-tab(cmux agent open) timed out the same way on the same Mac.Context: manaflow-ai/cmuxterm-hq#6338 (comment 6597127823). #34405 (merged) hides the notice by retrying; this fixes why the daemon was slow to answer. A sibling change handles the notices themselves; this PR touches no UI and adds no Swift.
Cause
workspace_group.updateis one short SQLite commit (under 1 ms idle). It commits under the one workspace registry lock (SignaledMutex<WorkspaceRegistry>), which every state write takes: on a busy Mac (about 50 agent sessions writing status, progress and logs) the lock is held most of the time.std::sync::Mutexis not fair: a waiter can lose to newcomers again and again, so the click's commit queued behind the whole crowd of background writers until the app's 2 s deadline. Persistence is not the problem: commits already reply before the disk (wal_durability.rs:synchronous=NORMAL, the syncer flushes off the request path), and the commit itself is unchanged here.Fix
mux/signaled_mutex.rs: a request a person waits on runs insideinteractive_scope(). Its registry locks go next after the current holder: while one waits, a plain locker neither queues for the lock nor keeps one it just won.MAX_INTERACTIVE_STREAK(4) interactive acquisitions go ahead of waiting plain lockers in a row; then interactive lockers step aside the same way until a plain one has taken the lock. Agents send personal writes too (workspace.place, group edits), so this keeps them from starving ordinary writers (status updates, workspace create/close).state/personal.rs(state_personal: every personal sidebar write: group create/update/move/delete,workspace.place, rooms) andstate/conversation_tabs.rs(new_conversation_tab_as) run in that scope.No new timer or loop at idle: a plain locker waits on the existing release condvar only while an interactive locker waits (20 ms timeout bounds a missed wakeup); nothing runs when nobody waits.
Trade-off and risk
Tests (red at base, green at head)
cargo test -p cmux-tui-core --lib group_update_latency_tests(run withcmux-ci test,set -o pipefail):a_persons_requests_answer_while_busy_sessions_saturate_the_registry: 48 sessions commitworkspace_status.setback to back (each commit holds the registry 5 ms), 4cmux agent opencallers open chat tabs, and a person collapses a group, moves a workspace and opens a chat tab 30 times each. Budget p95 < 100 ms for the sidebar writes, < 200 ms for the chat tab; the last fold must be in the registry file after a restart. Red at base (9f536b8: 480 / 494 / 2659 ms p95), green at head in 3 of 3 rounds (04ad745 and again at the final head 3e02bae, which only reorders ausefor rustfmt).ordinary_registry_writers_progress_while_personal_writes_stay_queued: 48 sessions sendworkspace_group.updateback to back with no pause; an ordinaryworkspace_status.setmust still answer (p95 < 1 s). Passes at base and head; it guards the starvation follow-up from review.The chat tab costs about 9 ms idle but takes the registry lock several times (browser row, presentation reload, topology commit) and shares interactive turns with the 4 agent-open callers, so it answers in about 65 ms p50 / 100 ms p95 under this load; its budget is 200 ms (10x under the app's 2 s deadline), and fewer registry takes per tab is a follow-up.
Performance
Same harness (
group_update_latency_tests, fast-checks Linux 8 vCPU, test profile), 48 busy sessions, 4 agent-open callers. Before: base code (run 41762350362, at 9f536b8). After: final head 04ad745, 3 rounds (run 41774733365); ranges across rounds.Background status throughput during the measured window falls (the person's requests and the agent-open callers go first), which is the intended trade.
Observed / Not run
cargo clippy -p cmux-tui-core --all-targets -- -D warningsis clean and the neighbor suites (state::,mux::tests::signaled_mutex,mux::tests::registry_reads,server::personal,server::agent_session_tabs: 259) pass.Changelog
Fixed: Collapsing or expanding a workspace group, moving a workspace and opening a chat tab answer quickly while many agents are busy.
Review: Codex (gpt-6.1-sol xhigh) range reviews, SHIP at 3e02bae; receipt in a comment.
Agent session: agent session
🤖 Generated with Claude Code