perf(acpmux): read background-process output sizes after releasing the session lock (SW-11)

Merged
TE
6d ago
+61-13

SW-11: stop holding the background-process mutex across filesystem reads

Source investigation: HQ SW-11 follow-up, specific process-history finding.

Root cause

_acpmux/process/list takes each session's std::sync::Mutex<ProcessTable> and used to call ProcessTable::values() while holding it. That method clones and serializes every entry and invokes std::fs::metadata on its outputFile. A slow or remote output file can consequently delay a running agent's process_update from obtaining the same table lock. Global process listings amplify the work across all loaded sessions. The old code scales with completed history.

Change

  • Make ProcessTable::snapshot() clone its ordered records under the lock, then drop the guard.
  • Resolve outputBytes and serialize the snapshot after unlocking for both a specified session and global listing.
  • Preserve live file-size refresh, row order, identifiers, completed status, process-list protocol and the current list's limitations. No new timer, data owner or API.
  • A new Rust unit test checks that the file-length callback can acquire the process-table lock, including on a completed task, and that the table's saved data stays unchanged.

Risk and performance

One copy of each process record was already made for every response; this changes when that copy occurs and shortens mutex occupancy. Serialized bytes and list cardinality stay the same. No measured latency gain claimed. File reads can still be slow, but now happen outside the mutex. The separate unpaged 15 MiB cap and O(N²) historical insert paths remain SW-11 follow-ups.

Performance

No perf numbers: this lock-contention fix does the same amount of filesystem and JSON work after releasing the mutex. The new unit test checks lock availability; a same-machine before/after contention or latency benchmark has not run.

Verification

  • Source compared against feat-cmux-next@07088897284b6637a4ddb5763e06ca1601d4aae2. One Rust file changed, one unit test added.
  • Not run here: Rust/Cargo or fleet CI; the connected environment lacks the repo toolchain. Please run cargo test -p acpmux --lib -- a_process_list_reads_output_metadata_after_releasing_its_table inside cmux-tui/, existing process integration suites, Clippy, and the managed NEXT compile before marking ready.
  • No UI/layout changes and no screenshots needed.

Changelog: Background-process listings take a snapshot before reading output-file sizes, leaving live process updates free to acquire their session lock.


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


Summary by cubic

Stops acpmux background-process listings from holding a session's process-table mutex while reading output-file sizes, so slow or remote output files no longer delay a running agent's process updates.

  • Clones the process rows under the lock, then reads outputBytes and serializes after releasing it, in both single-session and global listings.
  • Threads the file-size lookup through an explicit callback, letting a unit test verify it can acquire the process-table lock, including on a completed task.
  • Preserves the wire format, row order, and list limitations; no measured latency gain is claimed.