Observe the pipe's AbortSignal through an abort algorithm - #7500
Conversation
The TS pipe watched its signal with an 'abort' event listener. A
synthetic dispatchEvent(new Event('abort')) on a live signal aborted the
pipe with an undefined reason, and an earlier user listener calling
stopImmediatePropagation() kept the abort from the pipe, which hung.
The pipe now registers a DOM abort algorithm, which runs before the
event's listeners and only for a real abort. The bootstrap reaches
AbortSignal::addAbortAlgorithm() through a new utils.addAbortAlgorithm,
which returns an AbortAlgorithmHandle; the pipe removes the algorithm
when it settles. The handle type is internal: not on the global scope
and excluded from the generated types.
Parity with C++. Behind the experimental typescript_implemented_streams
flag.
|
LGTM! |
guybedford
left a comment
There was a problem hiding this comment.
Verified locally: piping-ts@, piping-cpp@ and basics-test@ pass, and with readable.ts reverted to main both syntheticAbortEventIgnored and stopImmediatePropagationDoesNotBlockAbort fail, so the regression coverage is real. Handle lifetime looks right: the registration stays reachable through the signal's traced algorithm list while it matters, and unregistering from a collected wrapper follows the existing EventHandler.abortHandler pattern.
One non-blocking note: this is the first path that runs a JS function inside runAbortSteps. Checked with a scratch test: an algorithm that throws propagates out of abort(), the remaining algorithms never run (the list is already cleared), native cancellations and the 'abort' event are skipped, while the signal stays aborted. The pipe's algorithm can't throw synchronously today, so this is fine as is, but the addAbortAlgorithmForBootstrap wrapper is the natural place to either catch and report or to state "must not throw" in the utils.addAbortAlgorithm contract. Follow-up is fine.
The TS pipe watched its signal with an 'abort' event listener. A synthetic dispatchEvent(new Event('abort')) on a live signal aborted the pipe with an undefined reason, and an earlier user listener calling stopImmediatePropagation() kept the abort from the pipe, which hung.
The pipe now registers a DOM abort algorithm, which runs before the event's listeners and only for a real abort. The bootstrap reaches AbortSignal::addAbortAlgorithm() through a new utils.addAbortAlgorithm, which returns an AbortAlgorithmHandle; the pipe removes the algorithm when it settles. The handle type is internal: not on the global scope and excluded from the generated types.
Parity with C++. Behind the experimental typescript_implemented_streams flag.