feat(daemon): app daemon-request latency probe (debug.daemon_requests)
LA
21h ago+282+282+012345678901234567890123456789-6-6-0123456789
Summary
Austin's 80-agent day (#27698) showed window-state saves that got "no reply within 2.0 s". The P-AUSTIN target for a fix is an app request p99 under 50 ms at 80 agents. Until now the app recorded no latency for its own requests to the daemon; only the time-outs show in its log. This PR adds a probe for that latency. The Austin's-day harness (#28077) reads it.
- What it records:
DaemonRequestLatencyis a fixed log-linear histogram: [0, 64 µs], then 4 buckets per power of two up to about 67 s, then an overflow bucket. It also counts errors and time-outs and keeps the maximum.- Each counter is a relaxed atomic. Recording takes no lock and allocates nothing per request. Its marks are
// perf-hot: 1us daemon-requestand a newdaemon-requestentry inperf-hot-benches.json.
- Each counter is a relaxed atomic. Recording takes no lock and allocates nothing per request. Its marks are
- Where it records:
LineTransport.requestrecords each request from send to reply or failure. The outcome is reply, error, or time-out (DaemonError.timedOut). - Who owns the probe: the local
DaemonServicemakes one probe and passes it in throughDaemonConnectionConfiguration.requestLatency. The prestart connection and every later connection record into that same probe. There is no static singleton. - How you read it:
debug.daemon_requests, answered off the main actor. It returns the bounds, the counts, errors, time-outs, the maximum, and p50/p95/p99. A reader diffs two reads to get a window.- The probe sits in
RequestLatencySlot, anonisolatedSendable class whose state is aMutex. The debug closure captures that class, notself.
- The probe sits in
- Debug and bench builds only. Release makes no probe and registers no
debug.*method. A debug path that works in Release would be a new socket surface, which needs its own policy review. The harness runs bench builds, so this case does not need one (lead decision, 2026-10-30).
Testing
- Red:
DaemonRequestLatencyTestsat 005bb70d92f (test only), step 202b74b54c46c9b5694a34ae on aws-m4pro-2: it fails. The test target does not compile:cannot find 'DaemonRequestLatency' in scope. That is the right reason: the type comes with the next commit. - Green:
DaemonRequestLatencyTestsat 4a78243dee2, step eea4a580abef5f23fe3f3e18 on cmux14: 3 of 3 tests passed. - Compile:
cmux-ci compile-check --app --package CmuxNext --recipe-version 2at 4a78243dee2, job d69b50218c13120ff0fba9f7: pass. Two earlier compiles failed and were fixed: - Prepush gate: clean.
Observed / Not run
- Observed: the red and green suite runs, the compile-check, and the prepush gate.
- Not run:
- The probe in a live app under load. The first Austin's-day run of a build with this probe will show its numbers.
- The probe's own cost (the
daemon-requestperf-hot bench). It has not run.
Changelog
none
Proof
No capture: no visible UI changes; this is a Debug and bench diagnostic.