Skip to content

Commit

Permalink
async-context
Browse files Browse the repository at this point in the history
  • Loading branch information
enisdenjo committed Dec 24, 2024
1 parent a8f6c92 commit 8750a83
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
32 changes: 32 additions & 0 deletions packages/graphql-modules/src/application/async-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { AsyncLocalStorage } from 'async_hooks';
import module from 'module';

export interface AsyncContext {
getApplicationContext(): GraphQLModules.AppContext;
getModuleContext(moduleId: string): GraphQLModules.ModuleContext;
}

let alc: AsyncLocalStorage<AsyncContext> | undefined;
if (typeof process !== 'undefined') {
// probably nodejs runtime
const require = module.createRequire(
'file:///' /** path is not relevant since we're only loading a builtin */
);
const hooks = require('async_hooks') as typeof import('async_hooks');
alc = new hooks.AsyncLocalStorage();
}

export function getAsyncContext() {
return alc?.getStore();
}

export function runWithAsyncContext<R, TArgs extends any[]>(
asyncContext: AsyncContext,
callback: (...args: TArgs) => R,
...args: TArgs
): R {
if (!alc) {
return callback(...args);
}
return alc.run(asyncContext, callback, ...args);
}
13 changes: 4 additions & 9 deletions packages/graphql-modules/src/application/context.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { AsyncLocalStorage } from 'async_hooks';
import { Injector, ReflectiveInjector } from '../di';
import { ResolvedProvider } from '../di/resolution';
import { ID } from '../shared/types';
import { once, merge } from '../shared/utils';
import type { InternalAppContext, ModulesMap } from './application';
import { getAsyncContext, runWithAsyncContext } from './async-context';
import { attachGlobalProvidersMap } from './di';
import { CONTEXT } from './tokens';

const alc = new AsyncLocalStorage<{
getApplicationContext(): GraphQLModules.AppContext;
getModuleContext(moduleId: string): GraphQLModules.ModuleContext;
}>();

export type ExecutionContextBuilder<
TContext extends {
[key: string]: any;
Expand Down Expand Up @@ -79,13 +74,13 @@ export function createContextBuilder({
});

appInjector.setExecutionContextGetter(function executionContextGetter() {
return alc.getStore()?.getApplicationContext() || appContext;
return getAsyncContext()?.getApplicationContext() || appContext;
} as any);

function createModuleExecutionContextGetter(moduleId: string) {
return function moduleExecutionContextGetter() {
return (
alc.getStore()?.getModuleContext(moduleId) ||
getAsyncContext()?.getModuleContext(moduleId) ||
getModuleContext(moduleId, context)
);
};
Expand Down Expand Up @@ -197,7 +192,7 @@ export function createContextBuilder({
return {
...env,
runWithContext(cb) {
return alc.run(
return runWithAsyncContext(
{
getApplicationContext() {
return appContext;
Expand Down

0 comments on commit 8750a83

Please sign in to comment.