Conversation
Worker pool now consults a MemoryGate before spawning a fresh runner. Defends against device OOM (system memory exhaustion across workers) and main-process heap OOM (V8 heap overrun from in-flight IPC payloads). Hot path stays unchanged when memory is plentiful: a cached freemem fast lane short-circuits the gate, and per-dispatch heap tracking is lazily enabled only after the slow lane first triggers. Cold-start sample window is intentionally undefended — first batch of workers spawns at full speed, samples back-feed the gate for subsequent spawns. PoolRunner is untouched: MemoryGate subscribes to the PoolWorker message stream directly. Pool only owns a small `tryWakeGateWaiter` callback; the poll timer lives in MemoryGate. Emergency kill switch via `RSTEST_MEMORY_AWARE=0` env var. Closes #1160
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b0f09c8886
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Rsdoctor Bundle Diff AnalysisFound 12 projects in monorepo, 1 project with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 core/mainPath:
📦 Download Diff Report: core/main Bundle Diff Generated by Rsdoctor GitHub Action |
MemoryGate stored heapBeforeDispatch as a single instance field, so concurrent dispatches clobbered each other's baselines. Resolves either computed the wrong delta or skipped sampling entirely once one resolve cleared the field, systematically underestimating heapDeltaSamples in the high-concurrency scenarios the slow lane is meant to defend. Return the baseline from recordDispatch and thread it through recordResolve so each dispatch carries its own token.
9aoy
approved these changes
May 14, 2026
Merged
This was referenced May 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
@rstest/core's worker pool scaled purely by CPU count, so low-RAM hosts (CI containers, smaller dev machines) could OOM the device when worker RSS piled up, or trip a V8 heap-limit crash in the host when many in-flight IPC payloads landed at once. Closes #1160.Implementation
MemoryGateconsulted inPool.acquireRunnerbefore each fresh spawn; defers when system memory or main-process heap headroom can't safely host another worker.os.freemem()fast lane (>= P90(rss) × 3) short-circuits; heap-delta tracking is lazily enabled only after the slow lane first fires.RSTEST_MEMORY_AWARE=0.PoolRunneris untouched.User Impact
Tests now defer worker spawns under memory pressure instead of OOM-ing. No public API or default-behavior changes when memory is plentiful.
Related Links
Closes #1160