Repository navigation
Make daemon startup fast, observable, and honestly reported - #882
Conversation
Startup vendor --version probes now run concurrently under one ceiling set above a single vendor's own budget: N vendors cost ~one probe and no outcome changes, so the transient-miss-never-disables invariant holds. A pre-host stderr phase trace records how far a boot got before the logger exists, and `daemon status` calls it starting, not serving, until its socket answers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Summary by QodoMake daemon startup fast, observable, and accurately reported
AI Description
Diagram
High-Level Assessment
Files changed (6)
|
Code Review by Qodo
1.
|
Four startup-path fixes: status keyed serving on a well-formed Hello, so a daemon built before the Hello frame — it accepts the connection and drops the unknown frame — read as still starting; socket reachability is the serving signal instead. Status now probes every live daemon at once, not one two-second timeout each. A version probe whose child exits while a descendant holds the redirected pipe no longer blocks forever draining to an EOF that never comes: the drains are bounded, and closing our read ends hands back the version buffered before the block rather than losing it. And daemon logs surfaces the stderr capture sibling, where the pre-host breadcrumbs land, rather than only the primary log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Codex exec review (on the review-round commit) Ran a local
Local verification: DaemonRunnerVersionProbeTests (incl. the bounded+recovered descendant case), DaemonRunnerConcurrentProbeTests, DaemonRunnerStartupPhaseTests, HelloProbeTests, DaemonStatusServingTests, DaemonLogsTests, and the ServiceVerify suites all green; both AOT publishes clean. |
Closes #859 — AI-2684
What & why
The version-probe deadlock that caused the multi-minute silent startup was fixed earlier (#869). This closes the three residuals that issue left open.
The vendor
--versionprobes ran sequentially before the host existed, so N bounded probes serialized ahead of the socket bind and the server connect. They now run concurrently under one wall-clock ceiling — strictly above a single vendor's own budget, so overlapping only removes the N-way serialization and never cuts a probe short; a vendor still unfinished at the ceiling is a miss the capability-refresh path re-probes. Startup now emits a phase trace ("lock acquired", "vendors probed", "host built", …) so a future stall shows the last phase reached, where before the pre-host window logged nothing. Andkcap daemon statusnow distinguishes a daemon that is serving from one whose PID is live but whose control socket does not yet answer, reporting "running (PID, starting — not yet serving)" instead of a flat "running".Where to look
The concurrent probe keeps each vendor's per-vendor budget; the ceiling is only a backstop above it.
statusdials the local control socket with a 2 s Hello — a bound daemon answers immediately, an unbound one refuses at once — so it does not hang.Deferred (a minor follow-up, not a core residual): moving the full vendor-list advertisement after connect. The list is produced by the gated-reviewer spawns that the connect path reads synchronously, so deferring it risks a brief no-reviewers window; the concurrency here already delivers the fast-startup goal.
Verification
statusreports serving vs still-starting from the Hello outcome. RegressionDaemonRunnerCursorAvailabilityTests37/37.