Skip to content

use single phase of resolver abortSignal cancellation#4554

Merged
yaacovCR merged 1 commit intographql:nextfrom
yaacovCR:single-cancellation-phase
Feb 11, 2026
Merged

use single phase of resolver abortSignal cancellation#4554
yaacovCR merged 1 commit intographql:nextfrom
yaacovCR:single-cancellation-phase

Conversation

@yaacovCR
Copy link
Contributor

@yaacovCR yaacovCR commented Feb 10, 2026

Previously, we used a lazily created abortSignal per resolver so as to shift triggering the abortSignal for a resolver that returned a streamed asyncIterable from the original executor to the stream. This is expensive and difficult to reason about and has been replaced by a single phase of cancellation when the entire execution finishes.

Note: when executing a subscription, we are still able to cancel resolver abortSignals after execution of each subscription event.

Additional note: this is labelled "bug fix" rather than "polish" because it is technically observable.

@yaacovCR yaacovCR requested a review from a team as a code owner February 10, 2026 20:29
@yaacovCR yaacovCR added the PR: bug fix 🐞 requires increase of "patch" version number label Feb 10, 2026
@vercel
Copy link

vercel bot commented Feb 10, 2026

@yaacovCR is attempting to deploy a commit to the The GraphQL Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@yaacovCR yaacovCR force-pushed the single-cancellation-phase branch 5 times, most recently from 157dec2 to c81de26 Compare February 11, 2026 14:01
Previously, we used a lazily created abortSignal per resolver so as to shift triggering the abortSignal for a resolver that returned a streamed asyncIterable from the original executor to the stream. This is expensive and difficult to reason about and has been replaced by a single phase of cancellation when the entire execution finishes.

Note: when executing a subscription, we are still able to cancel resolver abortSignals after execution of each subscription event.
@yaacovCR yaacovCR force-pushed the single-cancellation-phase branch from c81de26 to fb285c6 Compare February 11, 2026 14:08
@yaacovCR
Copy link
Contributor Author

In particular, the "confusion" regarding tying resolver abortSignals to particular Executors lies with incremental delivery.

What we'd like to do is trigger the abortSignal if that resolver should be cancelled because of null bubbling, but we don't currently have a mechanism to scan downwards in the path tree from the location to which the null bubbles. So what we do instead is just wait until execution "ends" and trigger the abortSignal for all resolvers.

But, in a situation of incremental delivery, if we scope the abortSignal to each individual executor, i.e. the root Executor and child executionGroup/streamItem Executors, we can no longer reliably trigger the abortSignal in all situations. Namely, for a resolver returning an async iterable for a list field that streams, the abortSignal could be checked in the middle of that stream, so if the abortSignal is scoped to the root executor, it would fire early. And so we end up having to create new abort controllers/signals for every resolver and move them from being triggered by the end of the root executor or the end of the stream, depending on whether they are streamed.

(And that's putting aside that in theory a resolver can return a construct that is fed forward into descendant fields, that in theory could misbehave once the parent abortSignal is triggered.)

Performing a single phase of abortSignal cancellation at the entire end of execution obviates all of the above, at the expense, of course, of delaying cancellation.

@yaacovCR yaacovCR merged commit 2d309c6 into graphql:next Feb 11, 2026
15 of 16 checks passed
@yaacovCR yaacovCR deleted the single-cancellation-phase branch February 11, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: bug fix 🐞 requires increase of "patch" version number

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant