diff --git a/src/execution/Executor.ts b/src/execution/Executor.ts index 68808d3678..2fb478538c 100644 --- a/src/execution/Executor.ts +++ b/src/execution/Executor.ts @@ -55,6 +55,8 @@ import { collectSubfields as _collectSubfields, } from './collectFields.js'; import { collectIteratorPromises } from './collectIteratorPromises.js'; +import type { SharedExecutionContext } from './createSharedExecutionContext.js'; +import { createSharedExecutionContext } from './createSharedExecutionContext.js'; import { buildResolveInfo } from './execute.js'; import type { StreamUsage } from './getStreamUsage.js'; import { getStreamUsage as _getStreamUsage } from './getStreamUsage.js'; @@ -224,26 +226,31 @@ export class Executor< validatedExecutionArgs: ValidatedExecutionArgs; aborted: boolean; abortReason: unknown; + sharedExecutionContext: SharedExecutionContext; collectedErrors: CollectedErrors; abortResultPromise: ((reason?: unknown) => void) | undefined; resolverAbortController: AbortController | undefined; - sharedResolverAbortSignal: AbortSignal; + getAbortSignal: () => AbortSignal | undefined; constructor( validatedExecutionArgs: ValidatedExecutionArgs, - sharedResolverAbortSignal?: AbortSignal, + sharedExecutionContext?: SharedExecutionContext, ) { this.validatedExecutionArgs = validatedExecutionArgs; this.aborted = false; this.abortReason = new Error('This operation was aborted'); this.collectedErrors = new CollectedErrors(); - if (sharedResolverAbortSignal === undefined) { + if (sharedExecutionContext === undefined) { this.resolverAbortController = new AbortController(); - this.sharedResolverAbortSignal = this.resolverAbortController.signal; + this.sharedExecutionContext = createSharedExecutionContext( + this.resolverAbortController.signal, + ); } else { - this.sharedResolverAbortSignal = sharedResolverAbortSignal; + this.sharedExecutionContext = sharedExecutionContext; } + const { getAbortSignal } = this.sharedExecutionContext; + this.getAbortSignal = getAbortSignal; } executeQueryOrMutationOrSubscriptionEvent(): PromiseOrValue< @@ -553,7 +560,7 @@ export class Executor< toNodes(fieldDetailsList), parentType, path, - () => this.sharedResolverAbortSignal, + this.getAbortSignal, ); // Get the resolve function, regardless of if its result is normal or abrupt (error). diff --git a/src/execution/createSharedExecutionContext.ts b/src/execution/createSharedExecutionContext.ts new file mode 100644 index 0000000000..d2eadbd57c --- /dev/null +++ b/src/execution/createSharedExecutionContext.ts @@ -0,0 +1,12 @@ +/** @internal */ +export interface SharedExecutionContext { + getAbortSignal: () => AbortSignal | undefined; +} + +export function createSharedExecutionContext( + abortSignal: AbortSignal | undefined, +): SharedExecutionContext { + return { + getAbortSignal: () => abortSignal, + }; +} diff --git a/src/execution/execute.ts b/src/execution/execute.ts index c157e9191b..1272749c37 100644 --- a/src/execution/execute.ts +++ b/src/execution/execute.ts @@ -34,6 +34,7 @@ import type { GraphQLSchema } from '../type/schema.js'; import { cancellablePromise } from './cancellablePromise.js'; import type { FieldDetailsList, FragmentDetails } from './collectFields.js'; import { collectFields } from './collectFields.js'; +import { createSharedExecutionContext } from './createSharedExecutionContext.js'; import type { ExecutionResult, ValidatedExecutionArgs } from './Executor.js'; import { Executor } from './Executor.js'; import { ExecutorThrowingOnIncremental } from './ExecutorThrowingOnIncremental.js'; @@ -598,6 +599,8 @@ function executeSubscription( ); } + const sharedExecutionContext = + createSharedExecutionContext(externalAbortSignal); const path = addPath(undefined, responseName, rootType.name); const info = buildResolveInfo( validatedExecutionArgs, @@ -605,7 +608,7 @@ function executeSubscription( fieldNodes, rootType, path, - () => externalAbortSignal, + sharedExecutionContext.getAbortSignal, ); try { diff --git a/src/execution/incremental/IncrementalExecutor.ts b/src/execution/incremental/IncrementalExecutor.ts index 52f2e5d5e3..c4f64baf9b 100644 --- a/src/execution/incremental/IncrementalExecutor.ts +++ b/src/execution/incremental/IncrementalExecutor.ts @@ -30,6 +30,7 @@ import type { } from '../collectFields.js'; import { collectSubfields as _collectSubfields } from '../collectFields.js'; import { collectIteratorPromises } from '../collectIteratorPromises.js'; +import type { SharedExecutionContext } from '../createSharedExecutionContext.js'; import type { ExecutionResult, FormattedExecutionResult, @@ -299,10 +300,10 @@ export class IncrementalExecutor< constructor( validatedExecutionArgs: ValidatedExecutionArgs, - sharedResolverAbortSignal?: AbortSignal, + sharedExecutionContext?: SharedExecutionContext, deferUsageSet?: DeferUsageSet, ) { - super(validatedExecutionArgs, sharedResolverAbortSignal); + super(validatedExecutionArgs, sharedExecutionContext); this.deferUsageSet = deferUsageSet; this.groups = []; this.tasks = []; @@ -314,7 +315,7 @@ export class IncrementalExecutor< ): IncrementalExecutor { return new IncrementalExecutor( this.validatedExecutionArgs, - this.sharedResolverAbortSignal, + this.sharedExecutionContext, deferUsageSet, ); } diff --git a/src/execution/legacyIncremental/BranchingIncrementalExecutor.ts b/src/execution/legacyIncremental/BranchingIncrementalExecutor.ts index 1e3f27a4ae..172fd3815b 100644 --- a/src/execution/legacyIncremental/BranchingIncrementalExecutor.ts +++ b/src/execution/legacyIncremental/BranchingIncrementalExecutor.ts @@ -179,7 +179,7 @@ export class BranchingIncrementalExecutor extends IncrementalExecutor { return new BranchingIncrementalExecutor( this.validatedExecutionArgs, - this.sharedResolverAbortSignal, + this.sharedExecutionContext, deferUsageSet, ); }