perf(cmux-tui): identical session registrations write nothing

TE
4d ago
+174-11

Repeated put-session registrations currently rewrite the session timestamp, append personal.session.put, advance the personal revision and emit personal-changed even when the effective record is identical. Subscribers then refetch the personal snapshot and journal maintenance wakes again.

Leo's ask: "see what's taking up all the cpu and optimize against that for acpmux/cmux-next and whatever agents try to do". The supplied 20 s headless-owner sample puts most control-dispatch time in WorkspaceRegistry::put_session.

Compare the validated, effective fields in the Rust transaction before writing. Omitted names/capabilities preserve stored values; a duplicate returns the existing timestamp and record. Real changes retain the existing transaction, journal and notification behavior. The wire handler uses the revision to distinguish a change from the existing created result.

Durability: the base already runs WAL with synchronous=NORMAL (128427b45cff), a background passive checkpoint and a close-time flush. This PR changes no pragmas or persistence policy and adds no timer, observer or cache. Each call still has one transaction; identical calls have no write commit.

Prior art read: #28056 (whole capabilities and app registration ledger), #28338 (reconnect epoch), #28289 (read paths do not write), #23190 (idle wakeups, closed). pr-overlap found no open overlap.

Caller trace: WindowManager starts SessionRegistrar. Its observation stream watches home personal revision/load/provisional state, home connection epoch, daemon load/registry IDs, and SSH/server auto-connect state. It builds one record per connected route and calls SessionRegistration.submit; the ledger suppresses identical records in flight or already recorded. There is no periodic, focus, layout or agent-session trigger here. The sampled NIGHTLY source already contains that ledger and WAL NORMAL. The sample has no RPC payloads, so the reason it still sends registrations frequently is not established by this change. Multiple routes exposing one registry ID with distinct records could bypass the ledger, but that condition is unproven; this fix covers identical effective records only.

Performance

Same disk-backed Rust harness, 32 registered machines with >=5765-byte capability lists, then 1024 identical puts. Counts come from the existing WAL hook and SQLite total_changes; elapsed excludes setup.

MetricBeforeAfterDeltaHarness
WAL commits / 1024 identical puts10240-100%repeated_session_puts_do_not_commit
Changed SQLite rows61440-100%same
Wall time1233.666 ms506.063 ms-59.0%same worker / same command

Validation

Added coverage for zero duplicate WAL commits/row writes, unchanged timestamps and snapshots, omitted fields, real updates, icon/migration preservation, invalid retries, and duplicate wire calls emitting no personal-changed. On fleet Linux job 752ef0fb10eb80befcce36cf, the same harness failed against the test-only pre-fix commit c7634933e8acb4356a09aefd30245007b1b2d660 with the measured writes, then passed at 8461c983921aeaa5fb2284a2aa81a1502fd58ae2. The effective-fields test and all 38 personal-state tests passed. The canonical fleet fallback ran the A/B after the initial overflow dispatch remained queued. Independent exact-head review: SHIP. These are workload measurements; the live Mac's CPU reduction has not been remeasured.

Final-head all-targets clippy reports exactly the same six diagnostics as base 20568cf5dbc3ac389315430ef15d658c7271e398, all in unchanged Cloud repository paths (cloud_repos/engine.rs, cloud_repos/runtime.rs, acpmux/agent_tools.rs, acpmux/cloud_repo_mcp.rs). The production panic-ratchet comparison passed in fleet job a904e6c5e7eb00ea2d0a837d with only base warnings; the subsequent commit changes a test loop only. The final combined job also repeats that ratchet comparison.

rustfmt and git diff --check pass. The broad Python preflight has existing localization-debt and workspace-package-grouping failures in files unchanged from the base. Localization audit adds or changes zero localized keys; protocol prose is the only text change.

Risk: last_seen_ms now denotes the last changed registration rather than a repeated identical registration. App code decodes the field but does not use it for presence/liveness. No Swift code changes.

Agent session: agent session