Skip to content

stream: keep writer async context for parked transform writes - #66908

Open
Timer wants to merge 1 commit into
nodejs:mainfrom
Timer:stream-parked-write-async-context
Open

Timer wants to merge 1 commit into
nodejs:mainfrom
Timer:stream-parked-write-async-context

Conversation

@Timer

@Timer Timer commented Oct 21, 2026 •

Copy link
Copy Markdown

When a TransformStream write parks on backpressure, the reader that clears the backpressure delivers the cached write continuation. The continuation was registered in the reader's async context. Thus transform() for the parked chunk, and for every later queued chunk, ran in the reader's context.

In the spec, a parked write is a reaction to [[backpressureChangePromise]], and the writable controller reacts to the sink write promise. Both reactions are registered at write time, so they run in the writer's context.

Store the async context frame when the write parks, and register the continuation in that frame. This gives the v24.20.0 behavior for AsyncLocalStorage again. If the reader runs in the same frame, the frame does not change.

Fixes: #66906
Refs: #65143
Refs: #65625

When a TransformStream write parks on backpressure, the reader that
clears the backpressure delivers the cached write continuation. The
continuation was registered in the reader's async context. Thus
transform() for the parked chunk, and for every later queued chunk,
ran in the reader's context.

In the spec, a parked write is a reaction to
[[backpressureChangePromise]], and the writable controller reacts to
the sink write promise. Both reactions are registered at write time,
so they run in the writer's context.

Store the async context frame when the write parks, and register the
continuation in that frame. This gives the v24.20.0 behavior for
AsyncLocalStorage again. If the reader runs in the same frame, the
frame does not change.

Fixes: nodejs#66906
Refs: nodejs#65143
Refs: nodejs#65625
Signed-off-by: Timer <timer@vercel.com>
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. web streams Issues and PRs related to the Web Streams API. labels Oct 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Welcome to Node.js, and thank you for your first contribution!

Before review, please take a moment to read:

Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal.

@codecov

codecov Bot commented Oct 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.57%. Comparing base (14ed05f) to head (e397072).

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #66908   +/-   ##
=======================================
  Coverage   90.57%   90.57%           
=======================================
  Files         797      797           
  Lines      278502   278517   +15     
  Branches    53540    53550   +10     
=======================================
+ Hits       252257   252273   +16     
+ Misses      16587    16579    -8     
- Partials     9658     9665    +7     
Files with missing lines Coverage Δ
lib/internal/webstreams/transformstream.js 98.80% <100.00%> (+0.02%) ⬆️

... and 24 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

needs-ci PRs that need a full CI run. web streams Issues and PRs related to the Web Streams API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

webstreams: transform() loses AsyncLocalStorage context after a parked write (regression in v24.22.0)

2 participants