mirror of
https://github.com/nestjs/nest.git
synced 2026-02-22 07:21:39 +00:00
Compare commits
2 Commits
v7.3.0
...
feature/as
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7250e42e5 | ||
|
|
6a084a36b6 |
@@ -144,6 +144,7 @@
|
||||
"packages/core/errors/**/*",
|
||||
"packages/common/exceptions/*.ts",
|
||||
"packages/common/http/*.ts",
|
||||
"packages/common/hooks/*.ts",
|
||||
"packages/common/utils/load-package.util.ts",
|
||||
"packages/microservices/exceptions/",
|
||||
"packages/microservices/microservices-module.ts",
|
||||
|
||||
63
packages/common/hooks/async-context.ts
Normal file
63
packages/common/hooks/async-context.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||
import * as asyncHooks from 'async_hooks';
|
||||
import { AsyncHooksHelper } from './async-hooks-helper';
|
||||
import { AsyncHooksStorage } from './async-hooks-storage';
|
||||
|
||||
export class AsyncContext implements OnModuleInit, OnModuleDestroy {
|
||||
private static _instance: AsyncContext;
|
||||
|
||||
private constructor(
|
||||
private readonly internalStorage: Map<number, any>,
|
||||
private readonly asyncHookRef: asyncHooks.AsyncHook,
|
||||
) {}
|
||||
|
||||
static getInstance(): AsyncContext {
|
||||
if (!this._instance) {
|
||||
this.initialize();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
onModuleInit() {
|
||||
this.asyncHookRef.enable();
|
||||
}
|
||||
|
||||
onModuleDestroy() {
|
||||
this.asyncHookRef.disable();
|
||||
}
|
||||
|
||||
set<TKey = any, TValue = any>(key: TKey, value: TValue) {
|
||||
const store = this.getAsyncStorage();
|
||||
store.set(key, value);
|
||||
}
|
||||
|
||||
get<TKey = any, TReturnValue = any>(key: TKey): TReturnValue {
|
||||
const store = this.getAsyncStorage();
|
||||
return store.get(key) as TReturnValue;
|
||||
}
|
||||
|
||||
run(fn: Function) {
|
||||
const eid = asyncHooks.executionAsyncId();
|
||||
this.internalStorage.set(eid, new Map());
|
||||
fn();
|
||||
}
|
||||
|
||||
private getAsyncStorage(): Map<unknown, unknown> {
|
||||
const eid = asyncHooks.executionAsyncId();
|
||||
const state = this.internalStorage.get(eid);
|
||||
if (!state) {
|
||||
throw new Error(
|
||||
`Async ID (${eid}) is not registered within internal cache.`,
|
||||
);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private static initialize() {
|
||||
const asyncHooksStorage = new AsyncHooksStorage();
|
||||
const asyncHook = AsyncHooksHelper.createHooks(asyncHooksStorage);
|
||||
const storage = asyncHooksStorage.getInternalStorage();
|
||||
|
||||
this._instance = new AsyncContext(storage, asyncHook);
|
||||
}
|
||||
}
|
||||
26
packages/common/hooks/async-hooks-helper.ts
Normal file
26
packages/common/hooks/async-hooks-helper.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as asyncHooks from 'async_hooks';
|
||||
import { AsyncHooksStorage } from './async-hooks-storage';
|
||||
|
||||
export class AsyncHooksHelper {
|
||||
static createHooks(storage: AsyncHooksStorage): asyncHooks.AsyncHook {
|
||||
function init(
|
||||
asyncId: number,
|
||||
type: string,
|
||||
triggerId: number,
|
||||
resource: Object,
|
||||
) {
|
||||
if (storage.has(triggerId)) {
|
||||
storage.inherit(asyncId, triggerId);
|
||||
}
|
||||
}
|
||||
|
||||
function destroy(asyncId) {
|
||||
storage.delete(asyncId);
|
||||
}
|
||||
|
||||
return asyncHooks.createHook({
|
||||
init,
|
||||
destroy,
|
||||
} as asyncHooks.HookCallbacks);
|
||||
}
|
||||
}
|
||||
11
packages/common/hooks/async-hooks-middleware.ts
Normal file
11
packages/common/hooks/async-hooks-middleware.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Injectable, NestMiddleware } from '@nestjs/common';
|
||||
import { AsyncContext } from './async-context';
|
||||
|
||||
@Injectable()
|
||||
export class AsyncHooksMiddleware implements NestMiddleware {
|
||||
constructor(private readonly asyncContext: AsyncContext) {}
|
||||
|
||||
use(req: any, res: any, next: () => void) {
|
||||
this.asyncContext.run(next);
|
||||
}
|
||||
}
|
||||
14
packages/common/hooks/async-hooks-module.ts
Normal file
14
packages/common/hooks/async-hooks-module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { AsyncContext } from './async-context';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [
|
||||
{
|
||||
provide: AsyncContext,
|
||||
useValue: AsyncContext.getInstance(),
|
||||
},
|
||||
],
|
||||
exports: [AsyncContext],
|
||||
})
|
||||
export class AsyncHooksModule {}
|
||||
31
packages/common/hooks/async-hooks-storage.ts
Normal file
31
packages/common/hooks/async-hooks-storage.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
export class AsyncHooksStorage {
|
||||
constructor(private readonly asyncStorage = new Map<number, unknown>()) {
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
get<T = any>(triggerId: number): T {
|
||||
return this.asyncStorage.get(triggerId) as T;
|
||||
}
|
||||
|
||||
has(triggerId: number): boolean {
|
||||
return this.asyncStorage.has(triggerId);
|
||||
}
|
||||
|
||||
inherit(asyncId: number, triggerId: number) {
|
||||
const value = this.asyncStorage.get(triggerId);
|
||||
this.asyncStorage.set(asyncId, value);
|
||||
}
|
||||
|
||||
delete(asyncId: number) {
|
||||
this.asyncStorage.delete(asyncId);
|
||||
}
|
||||
|
||||
getInternalStorage(): Map<number, unknown> {
|
||||
return this.asyncStorage;
|
||||
}
|
||||
|
||||
private initialize() {
|
||||
const initialAsyncId = 1;
|
||||
this.asyncStorage.set(initialAsyncId, new Map());
|
||||
}
|
||||
}
|
||||
3
packages/common/hooks/index.ts
Normal file
3
packages/common/hooks/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './async-context';
|
||||
export * from './async-hooks-middleware';
|
||||
export * from './async-hooks-module';
|
||||
@@ -10,6 +10,7 @@ export * from './cache';
|
||||
export * from './decorators';
|
||||
export * from './enums';
|
||||
export * from './exceptions';
|
||||
export * from './hooks';
|
||||
export * from './http';
|
||||
export {
|
||||
ArgumentMetadata,
|
||||
|
||||
Reference in New Issue
Block a user