Repository navigation
fix(service): wait out the evicted launchd job before repair bootstraps - #7200
vadymhimself wants to merge 1 commit into
Conversation
|
@coderabbitai review |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
✅ Action performedReview finished.
|
|
✅ Deterministic PR hygiene checks passed. |
d3075f5 to
f730646
Compare
⏳ DRAFT
What to do
Review readiness checklist
0/4 boxes ticked. This PR stays in draft until every box above is ticked. |
`launchctl bootout` returns at once while the old job keeps its label (`state = SIGTERMed`) until the process exits, and `bootstrap` fails with 5 for that whole window. The proxy drains on SIGTERM for up to `shutdownTimeoutMs` (5 s default), but the settle loop gave up after 1 s, so repair bootstrapped into the window, its retry and rollback raced it too, and the old job then exited leaving the service unloaded and stopped. Settle for up to 25 s, bounded by launchd's default 20 s ExitTimeOut. Co-Authored-By: Claude Code <noreply@anthropic.com>
f730646 to
dddf2a2
Compare
|
Being carried into #7225 with your authorship preserved; this PR will be closed when the bundle lands. |
…s and usage metering (#7194, #7201, #7176, #7177, #7178, #7179, #7199, #7202, #7189, #7190, #7200) (#7225) Carried from #7194, #7201, #7176, #7177, #7178, #7179, #7199, #7202, #7189, #7190, #7200 (one commit per source PR, original author preserved). #7205 held: replay can relocate server-tool exchanges into an earlier assistant turn. Remote validation (hosted GitHub Actions unreliable; local tests not run by maintainer rule): union candidate codex/prr-integ-8 = dev c03eafd + #7224 + #7223 + #7225 + #7217 + #6454 + #6594 plus a Gentle Shell import-cycle fix (integ-9 e1f289c: typecheck + full suite on mini (Windows) and lidge (Linux), compared with the same host's dev runs) and a test-only Windows path-escaping fix for the reasoning-retention routing test (integ-10 0d4cba7, tree a2b309a: that file re-run on both hosts). Co-authored-by: Vadym O <bolein95@gmail.com>
Summary
On macOS,
ocx service repaircould take a serving service down and leave it unloaded and stopped.Incident: a macOS host had a pre-2.66 launchd plist (the old launcher form with
KeepAliveset to true) and the proxy was serving under that job. Oneocx service repairproduced this sequence:service.logprinted🛑 Shutting down opencodex proxy....Bootstrap failed: 5.launchctl kickstartanswered "Could not find service". The operator had to runlaunchctl bootstrapby hand to get the service back.Root cause.
installLaunchdevicts the job withbootout, waits for it to settle, then runsbootstrap. That settle step gave up after 5 × 200 ms. I measured the launchd behaviour with a throwaway label whose process takes 6 s to exit on SIGTERM (macOS 26, Darwin 25.6):bootoutreturns 0 immediately.launchctl printkeeps answering 0 withstate = SIGTERMeduntil the process exits.bootstrapin that window fails with5: Input/output error.printreturn 113 andbootstrapsucceed.The proxy drains on SIGTERM for up to
shutdownTimeoutMs(5 s by default), and the launcher waits for it. So repair's first bootstrap landed inside that window, and so did everything after it:loaded-stale.kickstartand evicts again, which only waits another 1 s.bootstrapalso failed. Itsprintcheck still succeeded against the exiting job, so the rollback looked like it worked.KeepAlivedid not apply.Fix: settle for up to 125 × 200 ms = 25 s. launchd's default
ExitTimeOutof 20 s, after which it sends SIGKILL, bounds the wait, so a wedged domain still reaches the existing diagnosable error rather than hanging. The wait only runs wherebootoutactually evicted something (exit 0). The healthy no-op repair and fresh installs never wait.Not changed, worth a follow-up: in this failure,
reportServiceServingsays "the existing registration was kept" because the draining old proxy still answers its health probe. It says that even when the registration is gone. With the eviction settled, that message no longer appears for this sequence.Verification
tests/service/launchd-repair.test.ts("a job still draining after bootout is waited out, so repair never strands the service"). It uses the existinglaunchctl/probe/sleepSync/plistPathseams and never touches real launchctl. The fake models the measured behaviour: afterbootoutthe label stays registered for 30 polls (about 6 s) while everybootstrapreturns 5.launchctl could not bootstrap …: Bootstrap failed: 5.reloaded: true, and the new plist is on disk.bun test tests/service/launchd-repair.test.ts: 61 pass, 0 fail.bun run typecheck: clean.bun run test:changed: 30271 pass, 11 fail. None of the failures come from this change:tests/service/service.test.ts(211 pass),tests/service/service-sqlite-home.test.ts(5 pass) andtests/cli/cli-access-audio-live.test.ts(36 pass) all pass when run on their own. They failed only under the full parallel run.tests/cli/cli-connect-readiness.test.ts("a rejected preferred runtime falls back…") fails the same way on cleandev(60bf4c7e0).bun run testlocally because concurrent worktrees were competing for the test lock. Full coverage is left to CI.Checklist
🤖 Generated with Claude Code
Summary by CodeRabbit
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
Required local validation passed; commands, results, and any full-suite exception are documented.
I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.