refactor(apple-runner): isolate startup budget mechanics - #3011
Conversation
Size Report
Startup median (7 runs, lower is better):
|
There was a problem hiding this comment.
1 issue found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/platform-apple/src/runner/runner-start-budget.ts">
<violation number="1" location="packages/platform-apple/src/runner/runner-start-budget.ts:54">
P2: `openRunnerStartBudget` leaves the caller-signal listener installed after the start settles, because `close` only clears the timer. Repeated runner starts on one long-lived signal accumulate listeners and retain each filtered controller; return cleanup from the signal resolver and invoke it from `close`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| exhausted.abort(runnerStartBudgetExhaustedError(timeoutMs, explicitTimeoutMs !== undefined)); | ||
| }, timeoutMs); | ||
| timer.unref?.(); | ||
| const startupSignal = resolveRunnerStartupSignal(options); |
There was a problem hiding this comment.
P2: openRunnerStartBudget leaves the caller-signal listener installed after the start settles, because close only clears the timer. Repeated runner starts on one long-lived signal accumulate listeners and retain each filtered controller; return cleanup from the signal resolver and invoke it from close.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/platform-apple/src/runner/runner-start-budget.ts, line 54:
<comment>`openRunnerStartBudget` leaves the caller-signal listener installed after the start settles, because `close` only clears the timer. Repeated runner starts on one long-lived signal accumulate listeners and retain each filtered controller; return cleanup from the signal resolver and invoke it from `close`.</comment>
<file context>
@@ -0,0 +1,124 @@
+ exhausted.abort(runnerStartBudgetExhaustedError(timeoutMs, explicitTimeoutMs !== undefined));
+ }, timeoutMs);
+ timer.unref?.();
+ const startupSignal = resolveRunnerStartupSignal(options);
+ const signal = startupSignal
+ ? AbortSignal.any([startupSignal, exhausted.signal])
</file context>
|
Reviewed at 5f62db4. The startup budget move is behavior-neutral and I found no blocking problem. Not blocking: the two dynamic imports of CI: checks are still queued. Coverage, Integration and Repo Guards exercise this route, so their results apply to this change. |
5f62db4 to
e8f1a11
Compare
e8f1a11 to
fb72443
Compare
|
Summary
First review layer for #2967. Move the runner start budget, caller cancellation race, and detached-start diagnostics into
runner-start-budget.ts. The session owner still registers the keyed lock before loading the budget code, preserving concurrent release ordering while keeping the new module out of public Apple facade import closures. No runner behavior or public API changes.Rebased on current
mainat3fe2e6929, finalfb7244388: production +128/−118 (net +10); tests +2/−5; fixtures/docs 0; 3 files. The old in-file budget implementation is removed; the small net growth is the module boundary and its import. Rename-aware gross diff: 253 lines.Validation
pnpm check:affected --runpassed atfb7244388(format, lint, typecheck, layering, fallow, build, 2,538 related tests). The speculative-start race test and 691 eager-closure assertions passed after moving the lazy load inside the lock. CI coverage, integration, and native lanes are pending; live device verification belongs to the completed top layer.