From 79e36c7ec2211f1a75363a202b93e029018b8380 Mon Sep 17 00:00:00 2001 From: Tom Klaver Date: Mon, 24 Jul 2023 16:52:32 +0200 Subject: [PATCH 1/3] Rename --- .../{execution-context.ts => execution-context-hooks.ts} | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) rename packages/graphql-modules/src/application/{execution-context.ts => execution-context-hooks.ts} (93%) diff --git a/packages/graphql-modules/src/application/execution-context.ts b/packages/graphql-modules/src/application/execution-context-hooks.ts similarity index 93% rename from packages/graphql-modules/src/application/execution-context.ts rename to packages/graphql-modules/src/application/execution-context-hooks.ts index b4e04eb19a..c6db1061af 100644 --- a/packages/graphql-modules/src/application/execution-context.ts +++ b/packages/graphql-modules/src/application/execution-context-hooks.ts @@ -1,9 +1,5 @@ import { createHook, executionAsyncId } from 'async_hooks'; - -export interface ExecutionContextPicker { - getModuleContext(moduleId: string): GraphQLModules.ModuleContext; - getApplicationContext(): GraphQLModules.AppContext; -} +import { type ExecutionContextPicker } from './execution-context.interface'; const executionContextStore = new Map(); const executionContextDependencyStore = new Map>(); From 4d9ce3092e2228c0b60bde38b51a5420666a7c8b Mon Sep 17 00:00:00 2001 From: Tom Klaver Date: Mon, 24 Jul 2023 16:55:18 +0200 Subject: [PATCH 2/3] Use AsyncLocalStorage for execution context if available --- .../execution-context-async-local-storage.ts | 29 +++++++++++++++++++ .../execution-context.interface.ts | 4 +++ .../src/application/execution-context.ts | 19 ++++++++++++ .../tests/execution-context.spec.ts | 3 +- 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 packages/graphql-modules/src/application/execution-context-async-local-storage.ts create mode 100644 packages/graphql-modules/src/application/execution-context.interface.ts create mode 100644 packages/graphql-modules/src/application/execution-context.ts diff --git a/packages/graphql-modules/src/application/execution-context-async-local-storage.ts b/packages/graphql-modules/src/application/execution-context-async-local-storage.ts new file mode 100644 index 0000000000..077a9aedc1 --- /dev/null +++ b/packages/graphql-modules/src/application/execution-context-async-local-storage.ts @@ -0,0 +1,29 @@ +import { AsyncLocalStorage } from 'async_hooks'; +import { type ExecutionContextPicker } from './execution-context.interface'; + +const executionContextStore = AsyncLocalStorage + ? new AsyncLocalStorage() + : undefined; + +export const executionContext: { + create(picker: ExecutionContextPicker): () => void; + getModuleContext: ExecutionContextPicker['getModuleContext']; + getApplicationContext: ExecutionContextPicker['getApplicationContext']; +} = { + create(picker) { + executionContextStore!.enterWith(picker); + return function destroyContext() {}; + }, + getModuleContext(moduleId) { + return executionContextStore!.getStore()!.getModuleContext(moduleId); + }, + getApplicationContext() { + return executionContextStore!.getStore()!.getApplicationContext(); + }, +}; + +export function enableExecutionContext() {} + +export function getExecutionContextStore() { + return executionContextStore; +} diff --git a/packages/graphql-modules/src/application/execution-context.interface.ts b/packages/graphql-modules/src/application/execution-context.interface.ts new file mode 100644 index 0000000000..d6cfb3d84e --- /dev/null +++ b/packages/graphql-modules/src/application/execution-context.interface.ts @@ -0,0 +1,4 @@ +export interface ExecutionContextPicker { + getModuleContext(moduleId: string): GraphQLModules.ModuleContext; + getApplicationContext(): GraphQLModules.AppContext; +} diff --git a/packages/graphql-modules/src/application/execution-context.ts b/packages/graphql-modules/src/application/execution-context.ts new file mode 100644 index 0000000000..4ec7851064 --- /dev/null +++ b/packages/graphql-modules/src/application/execution-context.ts @@ -0,0 +1,19 @@ +import { AsyncLocalStorage } from 'async_hooks'; + +/* + Use AsyncLocalStorage if available (available sync Node 14). + Otherwise, fall back to using async_hooks.createHook +*/ + +import * as Hooks from './execution-context-hooks'; +import * as Async from './execution-context-async-local-storage'; + +export type { ExecutionContextPicker } from './execution-context.interface'; + +export const executionContext = AsyncLocalStorage + ? Async.executionContext + : Hooks.executionContext; + +export const enableExecutionContext = AsyncLocalStorage + ? () => undefined + : Hooks.enableExecutionContext; diff --git a/packages/graphql-modules/tests/execution-context.spec.ts b/packages/graphql-modules/tests/execution-context.spec.ts index 766b3c7cd4..5804d22db1 100644 --- a/packages/graphql-modules/tests/execution-context.spec.ts +++ b/packages/graphql-modules/tests/execution-context.spec.ts @@ -9,10 +9,11 @@ import { InjectionToken, testkit, } from '../src'; + import { getExecutionContextDependencyStore, getExecutionContextStore, -} from '../src/application/execution-context'; +} from '../src/application/execution-context-hooks'; const posts = ['Foo', 'Bar']; From d1036a94a1383961da17acc419f8193e15a15fe6 Mon Sep 17 00:00:00 2001 From: Kamil Kisiela Date: Tue, 25 Jul 2023 11:02:02 +0200 Subject: [PATCH 3/3] Create hip-elephants-warn.md --- .changeset/hip-elephants-warn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hip-elephants-warn.md diff --git a/.changeset/hip-elephants-warn.md b/.changeset/hip-elephants-warn.md new file mode 100644 index 0000000000..1070dba214 --- /dev/null +++ b/.changeset/hip-elephants-warn.md @@ -0,0 +1,5 @@ +--- +"graphql-modules": minor +--- + +Use AsyncLocalStorage for execution context if available