You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
test(server): count leaked PR cache caller data without WeakRefs - #35694
Flaky test, not a product bug. The Check failure only aggregates the Test Server 2 failure: PullRequestReadCache.test.ts 'does not keep a caller's data alive after its reads and invalidations' (expected 2 to equal 0). Run once at a time it passed 20/20; repeated 300x in one process it failed about 10% of the time. Heap snapshots of three failing runs show the surviving sweep data held only by V8's weak_refs_keep_during_job list: the test's own new WeakRef(groups) keeps the target alive until the current job ends, and the Effect.yieldNow before gc() does not reliably get past that point. The cache itself retained nothing. The fix drops WeakRefs: sweep data is a per-test marker class (SweepData extends Map) and the test asserts v8.queryObjects(SweepData, { format: 'count' }) === 0, which runs a full GC first and creates no WeakRef. The --expose-gc/vm gc setup and the yieldNow are removed. A copy that leaks the data into a module-level array still fails (expected 5 to equal 0), so the test still catches real retention. Node prints an ExperimentalWarning for v8.queryObjects on stderr; it does not fail the run.
Reproduction on main
Run the failing check on main.
Evidence
The checks on this pull request are the proof: it changes what main's checks run, not what the app does.
Tests
Before the fix: vp test run src/pullRequest/PullRequestReadCache.test.ts -t 'does not keep a caller' 20x passed 20/20; the case repeated 300x in one process failed 32/300 (and ~10% under CPU load). After the fix: the 300x in-process repeat passed 300/300 under CPU load and 300/300 without load; a deliberately leaking copy failed as expected; vp test run src/pullRequest/PullRequestReadCache.test.ts run 20x in a row: 20/20 passed (12 tests each); vp run check:changed passed (format, lint, knip, graphql, typecheck of 3 packages, tests).
Not in this change
Node prints an ExperimentalWarning for v8.queryObjects() on stderr; it does not affect the result.
Who did the work
Written by Claude Opus 5.5, in Claude Code
Reviewed by GPT-6.1 Sol, in Codex, and by Claude Opus 5.5, each on its own
The PR cache retention test failed about 1 in 10 runs with "expected 1 (or
2) to equal 0". A heap snapshot of a failing run shows the surviving sweep
data held only by V8's keep-during-job list: `new WeakRef(target)` keeps the
target alive until the current job ends, and `Effect.yieldNow` does not
reliably cross that boundary. The cache itself was not retaining anything.
Count live instances of a per-test marker class with `v8.queryObjects`,
which runs a full GC first and creates no WeakRef, instead of
WeakRef + yieldNow + gc().
AI-assisted; verified with the tests and tools listed above.
Macroscope's review found this PR approvable — This change is confined to an ignored server cache test. It does not change product defaults or introduce diagnostic suppressions, and no material production risk is identified.
Notes:
No code objects were reviewed. Approvability was decided on eligibility alone.
You can add or adjust custom eligibility rules. Learn more.
Reviewing files that changed from the base of the PR and between 93b5833 and 146c6bd.
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Trigger review
No actionable comments were generated in the recent review.
Walkthrough
The cache sweep test removes its explicit-GC setup and weak-reference tracking. It marks sweep data with a Map subclass and uses NodeV8.queryObjects to assert that no instances remain.
Changes: Cache sweep test
Layer / File(s)
Summary
Sweep data lifetime assertion apps/server/src/pullRequest/PullRequestReadCache.test.ts
The test removes the node:vm GC setup and weak-reference count. It uses a SweepData subclass of Map and checks the instance count with NodeV8.queryObjects.
pingdotgg/t3code#25285: Adds the earlier weak-reference sweep-data test and changes PullRequestReadCache.ts.
pingdotgg/t3code#25267: Adds the weak-reference regression test that this change replaces.
Suggested reviewers:yuruzuu, macroscopeapp
Merge Risk: Minimal · previous review 93b58
This change only updates a test and does not affect product behavior. No actionable merge-blocking risk remains.
Pre-merge checks: 4
Check name
Status
Explanation
Title check
The title names the main change: the PullRequestReadCache test now counts leaked caller data without WeakRefs. It follows the conventional commit format and matches the summary and objectives, which d…
Description check
The description covers the problem (a flaky test caused by the test's own WeakRef), the change (SweepData marker class and v8.queryObjects count), and verification with specific before/after results. …
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Full details: Title check
Explanation
The title names the main change: the PullRequestReadCache test now counts leaked caller data without WeakRefs. It follows the conventional commit format and matches the summary and objectives, which describe replacing the WeakRef-based check with a SweepData marker class and v8.queryObjects.
Full details: Description check
Explanation
The description covers the problem (a flaky test caused by the test's own WeakRef), the change (SweepData marker class and v8.queryObjects count), and verification with specific before/after results. It omits a Scope section linking an issue or stating why no issue is needed, and the Reproduction on main section is a bare instruction without steps. The Evidence section is an unusual addition. The Problem and Change sections are present as headings but are not labeled to match the template's sections exactly. Overall the description is mostly complete, so it passes.
Finishing Touches
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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
size:S10-29 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.
1 participant
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.
Flaky test, not a product bug. The Check failure only aggregates the Test Server 2 failure: PullRequestReadCache.test.ts 'does not keep a caller's data alive after its reads and invalidations' (expected 2 to equal 0). Run once at a time it passed 20/20; repeated 300x in one process it failed about 10% of the time. Heap snapshots of three failing runs show the surviving sweep data held only by V8's weak_refs_keep_during_job list: the test's own
new WeakRef(groups)keeps the target alive until the current job ends, and theEffect.yieldNowbeforegc()does not reliably get past that point. The cache itself retained nothing. The fix drops WeakRefs: sweep data is a per-test marker class (SweepData extends Map) and the test assertsv8.queryObjects(SweepData, { format: 'count' }) === 0, which runs a full GC first and creates no WeakRef. The --expose-gc/vm gc setup and the yieldNow are removed. A copy that leaks the data into a module-level array still fails (expected 5 to equal 0), so the test still catches real retention. Node prints an ExperimentalWarning for v8.queryObjects on stderr; it does not fail the run.Reproduction on main
Run the failing check on main.
Evidence
The checks on this pull request are the proof: it changes what main's checks run, not what the app does.
Tests
Before the fix:
vp test run src/pullRequest/PullRequestReadCache.test.ts -t 'does not keep a caller'20x passed 20/20; the case repeated 300x in one process failed 32/300 (and ~10% under CPU load). After the fix: the 300x in-process repeat passed 300/300 under CPU load and 300/300 without load; a deliberately leaking copy failed as expected;vp test run src/pullRequest/PullRequestReadCache.test.tsrun 20x in a row: 20/20 passed (12 tests each);vp run check:changedpassed (format, lint, knip, graphql, typecheck of 3 packages, tests).Not in this change
Who did the work
Run by the t3code factory in T3 Code.