Сервіс контексту
Сервіс контексту дозволяє зберігати та отримувати контекст у межах асинхронних викликів, що дозволяє вам передавати та отримувати дані, які пов'язані з поточним викликом, через асинхронний стек викликів. Він надає слідуючі можливості:
- Передача контексту між асинхронними викликами: Створення контекст на початку асинхронного виклику в адаптерах протоколів та можливість його використання на всій протяжності обробки запиту чи події.
- Управління логікою виконання: Контекст може бути використаний для передачі стану або метаданих про виконання, що дозволяє керувати поведінкою обробників.
- Діагностика та налагодження: Полегшення відстеження асинхронних викликів, а також виявлення помилок шляхом передачі додаткової інформації про контекст в логи або системи моніторингу.
- Інструменти аналізу продуктивності: Контекст може бути використаний для збору даних про продуктивність та
використання ресурсів у межах окремих кінцевих маршрут чи подій, що в подальшому
X-Fiberреалізовувати - створення просунутої статистики навантаження з можливостями повного аналізу роботи обробників.
Архітектура
Робота сервісу контексту ґрунтується на використанні вбудованої
бібліотеки async_hooks у середовищі Node.js. Це надає можливість різним
частинам ядра обчислень отримувати доступ до контексту кінцевих маршрутів або подій. Сам сервіс надає методи для
створення та видалення сховища контексту, які широко використовуються в адаптерах протоколів.
При отриманні запиту адаптер конкретного протоколу формує контекст запиту, включаючи знімок бізнес-схеми, IP-адресу, опис маршруту та інші відомості. Після цього адаптер визначає кінцевий маршрут та відповідний обробник у бізнес-схемі, щоб викликати його, передаючи контекст та інші важливі дані, наприклад, об'єкт запиту.
Крім того, контекст надається сервісу бізнес-схеми для створення методів роботи з бізнес-схемою. Ці методи надають доступ до документів тієї самої прикладної області, в якій був отриманий запит, і подальшого використання в агенті бізнес-схеми.
Застосування
Сервіс використовується виключно в ядрі обчислень для передачі контексту викликаного обробника запиту чи події.
import { inversify } from '~packages';
import { CoreSymbols } from '~symbols'
import { AbstractHttpAdapter } from './abstract.http.adapter';
import type {
IAbstractFrameworkAdapter,
NAbstractHttpAdapter,
NSchemeService,
IContextService,
NContextService
} from '~types'
const { injectable } = inversify;
@injectable()
export class FastifyHttpAdapter extends AbstractHttpAdapter<"fastify"> implements IAbstractFrameworkAdapter {
protected readonly _ADAPTER_NAME = FastifyHttpAdapter.name;
protected _CONFIG: NAbstractHttpAdapter.Config | undefined;
protected _instance: NAbstractHttpAdapter.Instance<"fastify"> | undefined;
private _schemas: NSchemeService.Services | undefined;
constructor(
// ... other inject structure
@inject(CoreSymbols.ContextService)
protected readonly _contextService: IContextService,
// ... other inject strucutre
) {
super();
}
public async start(): Promise<void> {
// ... other handler logic
this._instance.all(this._CONFIG.urls.api + "*", this._apiHandler);
// ... other handler logic
}
protected _apiHandler = async (
req: NAbstractHttpAdapter.Request<"fastify">,
res: NAbstractHttpAdapter.Response<"fastify">
): Promise<void> => {
// ... other handler logic
const store: NContextService.Store = {
service: schemaResult.service,
domain: schemaResult.domain,
action: schemaResult.action,
method: req.method,
path: req.url,
ip: req.ip,
requestId: v4(),
schema: this._schemas,
language: contextLanguage,
};
try {
await this._contextService.storage.run(store, async () => {
const context: NAbstractHttpAdapter.Context = {
store: store,
user: {},
system: {},
};
// ... execute handler logic
const result = await action.handler(
// ... other args
context
);
})
} catch (e) {
// ... exception catch logic
} finally {
this._contextService.exit();
}
};
}
де:
FastifyHttpAdapter- клас стратегіїhttpадаптераfastify.start- метод, який виконується при запускуhttpадаптера._apiHandler- приватний метод, який описує обробку кінцевих маршрутів, які надходять поAPIпоhttp._this._contextService.storage.run- створення простору виконання запиту.context- контекст виконання запиту.await action.handler(...- виконання обробника кінцевого маршруту.this._contextService.exit();- закриття простору виконання запиту.