Skip to content

Preserve AbortSignal.any cancellation before source listeners run - #59464

Open
Marve10s wants to merge 1 commit into
react:mainfrom
Marve10s:fix/abort-signal-dependent-cancellation
Open

Marve10s wants to merge 1 commit into
react:mainfrom
Marve10s:fix/abort-signal-dependent-cancellation

Conversation

@Marve10s

Copy link
Copy Markdown
Contributor

Summary:

AbortSignal.any() currently connects its inputs through public abort listeners. An earlier listener can stop event propagation and leave the combined signal active after its source is cancelled. It can also observe stale cancellation state, or trigger a second source that incorrectly replaces the first abort reason.

Track dependent signals internally and mark all of them aborted before dispatching the source's event. Dispatch the dependent events afterward, in registration order. Flattening nested combinations preserves the same ordering through chains; weak source references and cleanup avoid retaining inputs after cancellation.

This follows the DOM signal-abort algorithm. The failures reproduce headlessly on React Native 0.88.0 and current main.

const first = new AbortController();
const second = new AbortController();
first.signal.addEventListener('abort', () => second.abort('second'));
const combined = AbortSignal.any([first.signal, second.signal]);
first.abort('first');
console.log(combined.reason);

Before: second. After: first, matching native behavior.

Changelog:

[GENERAL] [FIXED] - Preserve AbortSignal.any() cancellation state and the first abort reason before source abort listeners run.

Test Plan:

From the repository root:

./node_modules/.bin/jest --runInBand --watchman=false --runTestsByPath packages/react-native/src/private/webapis/dom/abort-api/__tests__/AbortSignal-any-test.js

All four tests pass. Running these tests against the unchanged main implementation fails all four assertions: propagation suppression, state during the source event, nested event order, and the reentrant first reason.

./node_modules/.bin/eslint --max-warnings 0 packages/react-native/src/private/webapis/dom/abort-api/AbortSignal.js packages/react-native/src/private/webapis/dom/abort-api/__tests__/AbortSignal-any-test.js packages/react-native/src/private/webapis/dom/abort-api/__tests__/AbortController-itest.js
./node_modules/.bin/prettier --check packages/react-native/src/private/webapis/dom/abort-api/AbortSignal.js packages/react-native/src/private/webapis/dom/abort-api/__tests__/AbortSignal-any-test.js packages/react-native/src/private/webapis/dom/abort-api/__tests__/AbortController-itest.js
npx --yes --package=flow-bin@0.337.0 flow focus-check --max-workers 2 packages/react-native/src/private/webapis/dom/abort-api/AbortSignal.js packages/react-native/src/private/webapis/dom/abort-api/__tests__/AbortSignal-any-test.js

ESLint, formatting, and focused Flow checking pass. Additional headless probes of the real runtime passed with native event dispatch enabled and disabled, including nested combinations, duplicate inputs, validation failures, and reference cleanup.

The existing Fantom any() test now runs inside Fantom.runTask because Fantom requires WeakRef construction and dereferencing inside its event loop. Fantom, native builds, the full Jest suite, and full-repository Flow checking were not run.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 25, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 25, 2026

This branch has not been deployed

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant