fix(resolve): fix GC-liveness bug in the loadBatchEntityFetch#1536
fix(resolve): fix GC-liveness bug in the loadBatchEntityFetch#1536ysmolski wants to merge 4 commits into
Conversation
The arena memory is invisible to GC. The method was allocating 1 element slice on the Go heap and referenced from the arena bytes. At some point GC collected that slice and pointer was poisoned. -race was indicating the problem very well. The fix is to allocate the slice in the arena memory, so its lifetime is tied to the lifetime of pooled objects.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughFixes a defer-capture bug in batch entity fetch cleanup, moves initial batch-stats bucket allocation onto the loader arena, extracts a shared nested-batching fixture, refactors two benchmarks to reuse it, and adds a GC-pressure regression test that runs many concurrent resolver executions. ChangesBatch entity fetch memory improvements
Nested batching test suite enhancements
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@v2/pkg/engine/resolve/resolve_test.go`:
- Around line 7761-7783: The concurrent test uses nestedBatchingFixture which
wires in fakeDataSourceWithInputCheck that calls require.Equal (which invokes
FailNow) from worker goroutines; change fakeDataSourceWithInputCheck so it does
not call require.Equal but instead performs a non-fatal comparison and returns a
descriptive error when inputs mismatch (so the error flows back through
ResolveGraphQLResponse and is reported from the goroutine), or alternatively
replace the require.Equal call with a plain if check that constructs and returns
an error; ensure nestedBatchingFixture still uses that updated
fakeDataSourceWithInputCheck so ResolveGraphQLResponse can propagate the failure
rather than causing FailNow in a non-test goroutine.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 363b42aa-f732-4772-aa5f-9c2cebeadf15
📒 Files selected for processing (2)
v2/pkg/engine/resolve/loader.gov2/pkg/engine/resolve/resolve_test.go
| // hiding them from the GC. | ||
| func TestNestedBatching_GCPressure(t *testing.T) { | ||
| prevGC := debug.SetGCPercent(1) | ||
| defer debug.SetGCPercent(prevGC) |
The arena memory is invisible to GC. The method was allocating 1 element slice on the Go heap and referenced from the arena bytes. At some point GC collected that slice and pointer was poisoned.
-race was indicating the problem very well.
The fix is to allocate the slice in the arena memory, so its lifetime is tied to the lifetime of pooled objects.