Repository navigation
feat(daemon): app daemon-request latency probe (debug.daemon_requests) - #28295
Conversation
…tLatency does not exist yet) The Austin's-day harness needs the app request p99 under load (#27698): a fixed log-linear histogram of each daemon request's send-to-reply time. These tests pin its bucket bounds, bucket lookup, outcome counts and percentiles.
Each request the app sends its local daemon (LineTransport.request) records its send-to-reply time, or its time to failure, into DaemonRequestLatency: a fixed log-linear histogram (0-64 us, then 4 buckets per power of two up to ~67 s, then overflow) of relaxed atomics, no lock and no allocation per request. Outcomes: reply, error, timed out. The local DaemonService makes one probe in Debug and bench builds and injects it through DaemonConnectionConfiguration (the prestart's connection and every later one record into it); Release makes none. debug.daemon_requests (Debug and bench builds, like debug.daemon, answered off the main actor) returns bounds, counts, errors, timeouts, max and p50/p95/p99. The Austin's-day harness (scripts/cmux-next/austins-day) diffs a read before and after its load for the app request p99 at 80 agents (#27698). perf-hot id daemon-request.
Compile b5a19cfe (a5e697f) failed: the method's closure captured the service's noncopyable Mutex property ('cannot consume noncopyable stored property'). The probe now sits in a RequestLatencySlot class that the closure captures by reference; the read borrows the probe and returns its copyable Snapshot.
…state Compile b65f309e (d8bb6ad) failed: CmuxNextDaemonService defaults to the main actor, so RequestLatencySlot's init and 'probe' were main-actor isolated and neither the service's nonisolated default value nor the off-main debug.daemon_requests closure could use them. The slot is now a nonisolated Sendable class (its state is a Mutex; no @unchecked); the closure captures the service's nonisolated let.
|
Owners (plans/cmux-next/OWNERS.md):
|
|
Found 6 test failures on Blacksmith runners: Failures
|
|
Independent review for awareness (codex gpt-6-astra, high, fast; read-only, no builds), at head The probe wraps only Also, No builds or tests were run, per instruction. VERDICT: BLOCK at 4a78243 — the latency probe omits all pipelined daemon requests, making its reported request statistics incorrect. |
# Conflicts: # Packages/macOS/CmuxNext/Sources/CmuxNextApp/Control/AppControl.swift # Packages/macOS/CmuxNext/Sources/CmuxNextDaemon/Connection/DaemonConnectionConfiguration.swift # Packages/macOS/CmuxNext/Sources/CmuxNextDaemon/Connection/LineTransport.swift # Packages/macOS/CmuxNext/Sources/CmuxNextDaemonService/DaemonService+LaunchSnapshot.swift # Packages/macOS/CmuxNext/Sources/CmuxNextDaemonService/DaemonService.swift
|
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)
web and size checks: green Shipped in:
|
|
Conflict wave: I merged feat-cmux-next (5f7b667, through merge-main.sh). The request-latency probe now sits together with feat's later daemon work: |
|
Review (codex gpt-6-astra high, next-review): SHIP at 5f7b667 SHIP at 5f7b667 Visual verdict: no images; Leo tries the build.
I could not run Swift tests locally because Swift is unavailable in this environment. Follow-ups:
|
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 (next-review patch-id; carried): SHIP at bcf0dac The independent SHIP at 5f7b667 carries to this head: the PR's own change ( |
|
Review (next-review patch-id; carried): SHIP at 288bcd9 The independent SHIP at 5f7b667 carries to this head: the PR's own change ( |
|
Review (next-review patch-id; carried): SHIP at 06aed84 The independent SHIP at 5f7b667 carries to this head: the PR's own change ( |
|
Review (next-review patch-id; carried): SHIP at feee283 The independent SHIP at 5f7b667 carries to this head: the PR's own change ( |
|
Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over. For awareness: this PR's |
…st in #28295's merge) (#32238) #29409 registered the local daemon's creation-hold and close-read-hold methods (debug.creation.hold/release, debug.close.hold/release) beside debug.daemon in AppControl. #28295 (debug.daemon_requests) landed after it with its own version of that line, which dropped both, so a Debug build answers those methods with an unknown-method error (scripts/cmux-next/typeahead-gate.sh and the journey fuzz use them). This restores them next to debug.daemon_requests. Agent-Session: https://cmux.com/deeplink/agent?id=aid-9124da39adbff74677d9 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Swift-logic note (REWRITE R-SWIFT-MIRRORS): this PR added Why this matters: the tip's Nothing to change in this merged PR. REWRITE R-SWIFT-MIRRORS tracks the move (design: https://cmux-orchestrator-1.tail137216.ts.net/resize-videos/rewrites/R-SWIFT-MIRRORS/DESIGN.md, section 11). |
|
Swift logic follow-up (tip watcher swift-logic row, STATUS 13027 "SWIFT LOGIC CULPRITS"; lead order). This PR raised
plans/cmux-next/layer-ownership.md says Rust owns every state, list and rule and Swift is the platform shell. Please move the new logic of this PR in a follow-up: to Rust (the crate that owns the area; the owner lists in STATUS 12147-12165 name the target per area), or at least out of the app into its package. If a declaration above is platform code (AppKit, Core Animation, OS calls, strings, tokens, DEBUG tooling), reply here and the table gets a PLATFORM row with your reason instead. The swift-logic row is a report, not a gate: nothing blocks on this comment. |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
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.
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.// perf-hot: 1us daemon-requestand a newdaemon-requestentry inperf-hot-benches.json.LineTransport.requestrecords each request from send to reply or failure. The outcome is reply, error, or time-out (DaemonError.timedOut).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.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.RequestLatencySlot, anonisolatedSendable class whose state is aMutex. The debug closure captures that class, notself.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
DaemonRequestLatencyTestsat 005bb70 (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.DaemonRequestLatencyTestsat 4a78243, step eea4a580abef5f23fe3f3e18 on cmux14: 3 of 3 tests passed.cmux-ci compile-check --app --package CmuxNext --recipe-version 2at 4a78243, job d69b50218c13120ff0fba9f7: pass. Two earlier compiles failed and were fixed:Mutex;Observed / Not run
daemon-requestperf-hot bench). It has not run.Changelog
none
Proof
No capture: no visible UI changes; this is a Debug and bench diagnostic.