Skip to content

fix(async-hooks): share ALS context with runtime provider - #8042

Merged
proggeramlug merged 2 commits into
PerryTS:mainfrom
proggeramlug:fix/8037-next-async-local-storage
Aug 13, 2026
Merged

fix(async-hooks): share ALS context with runtime provider#8042
proggeramlug merged 2 commits into
PerryTS:mainfrom
proggeramlug:fix/8037-next-async-local-storage

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • move AsyncLocalStorage context mutation/read operations behind an explicit C ABI owned by the runtime provider
  • keep run() / exit() throw-safe restoration in the runtime image so promise, timer, microtask, dynamic-import, and stream schedulers snapshot the same ACTIVE_CONTEXT
  • add a focused Next App Route continuation fixture covering action/request/work/work-unit stores, interleaved IDs, nested throw/rejection, post-rejection reuse, and lifecycle cleanup

This is a non-closing, focused lower-level part of #8037. The pinned production AppRouteRouteModule.handle integration gate and 20-request verifier remain tracked by #8034; this PR does not add a direct-handler compatibility path or claim that production acceptance gate.

Validation

  • cargo fmt --all -- --check
  • cargo test --profile perry-dev -p perry-runtime async_context::tests::als_provider_abi_keeps_nested_run_and_exit_scopes_balanced -- --exact --nocapture
  • PERRY_SKIP_BUILD=1 ... ./run_parity_tests.sh --suite node-suite --module async_hooks --filter next-route-continuations
  • the focused fixture compiled as an app-only dylib with --output-type dylib, loaded by a C host, and matched its Node oracle
  • 100/100 executable repetitions of the focused fixture matched its Node oracle
  • existing focused propagation cases passed: concurrent-promises, promise-microtask, promise-catch-finally, and nexttick-timer

No version bump.

Refs #8037

@coderabbitai

coderabbitai Bot commented Aug 13, 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: 4ff637b6-be49-4387-9d5e-a46747ed4433

📥 Commits

Reviewing files that changed from the base of the PR and between 05394df and d93adea.

📒 Files selected for processing (5)
  • changelog.d/8042-next-route-async-local-storage.md
  • crates/perry-runtime/src/async_context.rs
  • crates/perry-stdlib/src/async_local_storage.rs
  • test-parity/node-suite/async_hooks/propagation/fixtures/next-route-lazy.js
  • test-parity/node-suite/async_hooks/propagation/next-route-continuations.ts

📝 Walkthrough

Walkthrough

The runtime adds a C ABI for AsyncLocalStorage context operations. The stdlib uses this ABI for scope and store management. New parity coverage tests concurrent route continuations, nested scopes, errors, streams, and cleanup.

Changes

AsyncLocalStorage propagation

Layer / File(s) Summary
Runtime context ABI and restoration
crates/perry-runtime/src/async_context.rs
The runtime exposes C ABI operations for entering and leaving run and exit scopes, reading and replacing stores, clearing handles, and restoring nested contexts.
Stdlib provider wiring
crates/perry-stdlib/src/async_local_storage.rs
AsyncLocalStorage delegates run, getStore, enterWith, exit, and disable to the shared async-context provider.
Concurrent route propagation coverage
test-parity/node-suite/async_hooks/propagation/*, changelog.d/8042-next-route-async-local-storage.md
The parity test checks four stores across concurrent route handlers, dynamic imports, promises, timers, errors, exit scopes, streams, rejection recovery, and post-route cleanup. The changelog records the coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Mergeability Score: ⚪ Minimal · up to d93ad

This change moves async-local context handling behind the runtime provider while preserving throw-safe scope restoration and adding focused continuation coverage. No actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant RouteHandlers
  participant AsyncLocalStorage
  participant RuntimeABI
  participant AsyncContinuations
  RouteHandlers->>AsyncLocalStorage: enter action, request, work, and work-unit stores
  AsyncLocalStorage->>RuntimeABI: register stores and scope guards
  RouteHandlers->>AsyncContinuations: run imports, promises, timers, microtasks, and streams
  AsyncContinuations->>AsyncLocalStorage: read propagated stores
  RouteHandlers->>AsyncLocalStorage: exit nested scope and handle rejection
  AsyncLocalStorage->>RuntimeABI: restore or clear context
Loading

Possibly related issues

Possibly related PRs

  • PerryTS/perry#6448 — This PR extends the related AsyncLocalStorage propagation semantics and coverage.

Suggested labels: bug, parity

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers the runtime ABI and focused propagation tests, but it does not demonstrate the required production AppRouteRouteModule.handle path or 20-request verifier. Add or reference the production dylib integration gate that invokes AppRouteRouteModule.handle and verifies 20 concurrent request IDs, cleanup, and rejection isolation.
✅ Passed checks (4 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The runtime, stdlib, fixture, test, and changelog changes support AsyncLocalStorage propagation objectives and do not introduce unrelated code.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly identifies sharing AsyncLocalStorage context with the runtime provider, which is the PR's primary change.
Description check ✅ Passed The description covers the changes, linked issue, validation, scope limits, and version policy, with only minor template omissions.
✨ 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 proggeramlug left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Audited exact head d93adeaa31de1562b541e57acf35ff7991fb3349.

The runtime-owned ALS provider ABI is internally coherent, and the focused unit test async_context::tests::als_provider_abi_keeps_nested_run_and_exit_scopes_balanced passes locally. I am holding the merge because this head claims to close #8037 without satisfying that issue's acceptance contract.

#8037 requires the pinned #8034 production AppRouteRouteModule.handle path, 20 concurrent requests, 100 repetitions, both executable and app-only dylib modes, and no direct-handler fallback. This PR exercises only the lower-level provider ABI and a focused parity fixture; the PR body itself describes it as the lower-level half.

Please either add and run the required production integration gate, or narrow the PR to a non-closing partial fix (Refs #8037 rather than Closes #8037). I can re-audit the updated exact head.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Agreed. I narrowed the PR description to a non-closing partial fix (Refs #8037) and clarified that the app-only dylib and 100-run validation apply to the focused fixture, not #8034’s production AppRouteRouteModule.handle gate. #8037 remains open pending that production integration gate.

@proggeramlug proggeramlug left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-audited exact head d93adea. The source is unchanged from the prior audit, the focused unit verification passed, the current-main merge tree is clean, and the description now correctly narrows this to a non-closing lower-level part of #8037. That resolves my only blocker.

@proggeramlug
proggeramlug merged commit a11093a into PerryTS:main Aug 13, 2026
37 of 58 checks passed
@proggeramlug
proggeramlug deleted the fix/8037-next-async-local-storage branch August 13, 2026 18:41
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.

1 participant