Skip to content

test(fetch): cover multi-app scanner registration - #8562

Merged
proggeramlug merged 1 commit into
PerryTS:mainfrom
proggeramlug:fix/8546-multi-runtime-isolation
Aug 22, 2026
Merged

test(fetch): cover multi-app scanner registration#8562
proggeramlug merged 1 commit into
PerryTS:mainfrom
proggeramlug:fix/8546-multi-runtime-isolation

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a current-thread scanner-count diagnostic so provider tests can inspect the thread-local FFI mutable-root registry without fabricating heap pointers
  • model Coop's two dedicated Perry application threads and assert that each installs exactly one Fetch scanner
  • document the multi-app Next dispatch fix without a version bump

Context

While #8546 was being investigated, #8552 landed the per-thread scanner-latch correction for the underlying bug class. It was not linked to #8546 and had only a static latch audit. This adds behavioral coverage for the exact Fetch path implicated here: with the old process-global Once, application 1 registers successfully and application 2 sees an empty scanner registry, leaving its Request, Headers, and FormData roots invisible to that heap's collector.

The regression was sabotage-verified by temporarily restoring the old Once: it fails deterministically with application 2 did not install the Fetch root scanner (left: 0, right: 1). Restoring the per-thread latch makes it pass.

Testing

  • cargo +nightly-2026-08-20 test -p perry-stdlib --no-default-features --features web-fetch fetch_root_scanner_registers_for_each_application_thread --lib -- --nocapture
  • python3 scripts/check_gc_scanner_latches.py
  • python3 scripts/gc_runtime_root_holders.py
  • scripts/check_file_size.sh
  • targeted rustfmt --check and git diff --check

No version bump; Cargo.toml and Cargo.lock are unchanged.

Fixes #8546

Summary by CodeRabbit

  • Bug Fixes

    • Fixed Fetch functionality in embedded multi-application environments so each application properly initializes its required data scanners.
    • Prevented Fetch request and header data from becoming unavailable to applications after the first one.
  • Tests

    • Added regression coverage confirming scanner registration works independently for multiple application threads.

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d1cff8e5-0758-4aab-a7b9-edf952f341d1

📥 Commits

Reviewing files that changed from the base of the PR and between 4ee1d04 and 4d8c394.

📒 Files selected for processing (3)
  • changelog.d/8546-multi-app-fetch-scanner.md
  • crates/perry-runtime/src/gc/roots.rs
  • crates/perry-stdlib/src/fetch/tests.rs

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The runtime now exposes the current thread’s named FFI mutable-root scanner count. A regression test verifies Fetch scanner registration for two sequential application threads. The changelog documents the multi-application fix.

Changes

Fetch scanner registration

Layer / File(s) Summary
Thread-local registration contract and regression test
crates/perry-runtime/src/gc/roots.rs, crates/perry-stdlib/src/fetch/tests.rs, changelog.d/8546-multi-app-fetch-scanner.md
The runtime reports the current thread’s named FFI mutable-root scanner count. The test verifies that each application thread registers the Fetch scanner once and does not register it twice. The changelog records the per-thread root behavior and regression coverage.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 4d8c3

This PR adds multi-application Fetch scanner coverage and a diagnostic for thread-local root registration; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. (1 skipped: 1 unsupported.) Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Fetch scanner registration test for multi-application support.
Description check ✅ Passed The description explains the change, linked issue, implementation context, tests, and version status, despite using different section names than the template.
Linked Issues check ✅ Passed The PR adds behavioral coverage for per-thread Fetch scanner registration, directly addressing the linked issue's multi-application heap-isolation concern.
Out of Scope Changes check ✅ Passed The diagnostic API, regression test, and changelog entry all support the stated multi-application Fetch scanner objective.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Merging as a validated batch. These six are the non-perf members of a nine-PR stack built on current main; the three perf PRs (#8568, #8570, #8573) are deliberately held back for measurement rather than merged on compile evidence.

Validation on the combined stack:

check result
cargo check --workspace --all-targets exit 0, zero errors
check_file_size.sh 0
workspace_architecture.py --check 0
raw_handle_debt.py 0
check_gc_scanner_latches.py 0
gc_runtime_root_holders.py 0
check_test_registration.py 0
cargo fmt --all -- --check 0

The stacked compile check is what per-PR CI cannot do: several of these touch the same files, and pairwise-green PRs can still break in combination.

The ratchets were re-run against the current baseline immediately before merging, not just during the initial audit. That distinction is not pedantry — #8560 passed raw_handle_debt at a baseline of 974, then #8559's cleanup lowered it to 925 and turned a legitimately-green change into a violation on main. A ratchet result is only valid as of the moment it ran.

Mechanical fixes applied while staging (these are fork PRs, so they could not be pushed to their branches): PR-keyed the changelog fragments for #8562 (was 8546-) and #8570 (was 8409-), and wrote the missing fragments for #8563, #8567 and #8574.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

coop/in_process: second Next app dies with TypeError: value is not a function (GC rooting, multi-heap)

1 participant