Conversation
…n test Spawning 10000 tasks at once grew the task set through several rehashes. JSC leaves an obsolete table's keys in place after a rehash, so a stale conservative stack word pointing at one kept ~8191 dead promises alive, failing intermittently on arm64 CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
MERGE Positive improvement: this is a real CI flake, not a leak in Worth it. A bulk-spawn-plus-stronger-GC approach would stay engine-fragile; shrinking the count would only paper over the rehash window. This is the right shape. This is an automated review, not the maintainer's decision |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 4 included reviews per hour; 0 remain after this review. WalkthroughThe spawn-retention test now spawns and settles each of 10,000 tasks before starting the next. The promise-count assertion remains unchanged. Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The test continues to check for settled-promise retention while avoiding the flaky concurrent-spawn setup. No material merge risk is evident. Architecture SummaryArchitecture risk: 🔵 Low · up to The change affects 1 system. Changed systems: Architecture concerns Review detailsSystems and components
Before / after behavior
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1⚔️ Resolve merge conflicts 💡
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Closing this. #4128 is already on main and rewrote (Written by Grok 4.7) |
Fixes the intermittent
spawn retention > an effect that never reruns drops settled tasksfailure on the arm64Testjob (received ~8191 instead of < 100).Root cause
Not a leak in
Effect.spawn. Spawning 10000 tasks synchronously grows#async(aSet) through several rehashes. JSC'sOrderedHashTablerehash marks the old storage obsolete but leaves its keys in place (copyImplonly overwrites the header with deleted-entry indices). Those obsolete tables are garbage, unless a stale word on the stack or in a register still points at one; JSC scans both conservatively. When that happens, the old tables keep ~8k settled promises alive.Reproduced locally by pinning the set's storage with an iterator taken mid-loop: the delta is exactly 8191 for any pin point during the add phase, vs 3 without. Whether a stale pointer survives depends on JIT tier and register allocation, hence arm64-only and run-to-run variance.
Fix
Settle each task before spawning the next, which is also how the real per-group caller behaves. The set never grows past one entry, so there are no large obsolete tables to retain. The test still fails without the fix (removing the
tasks.deleteline gives 10003).API / wire impact
None (test only).
🤖 Generated with Claude Code
(Written by Claude Opus 5.5)