@maeum/async-context
TypeScript icon, indicating that this package has built-in type declarations

1.2.0 • Public • Published

@maeum/async-context

ts Download Status Github Star Github Issues NPM version License ci code style: prettier

Packages for enhance async context mechanishm

Why @maeum/async-context?

async context is a new proposal that is in Stage 2. It's a replacement for Domain after it was removed from the Node.js environment, and a way to manage context in an efficient way. When you run an async function, you specify a store to share, and then the store can be accessed by the async function and other functions run by the async function.

For example, in fastify.js, each request is given a unique ID. This unique ID can be useful for analyzing DB query errors, analyzing slow queries, tracking logic errors, and more. In order to log the ID, you have to pass the request object, but with async-context, you can get the context, ID, etc. without passing the request object. You can use the fastify-request-context plugin to add an async-context to a request, and you can use @maeum/async-context to explore the async-context you've added.

  1. adding an async-context to the fastify.js FastifyRequest object
  2. navigate to the async-context even if you don't pass a FastifyRequest object

Table of Contents

Getting Starts

npm i @maeum/async-context --save

How it works?

flowchart TD
    B[AsyncLocalStore]
    C[AsyncResource]
    D[async function]
    E[nested async function - 01]
    F[nested async function - 02]
    G[nested async function - 03]
    H[nested function - 01]

    B --> C
    C --> D
    D --> E
    D --> G
    G --> H
    E --> F

    D -.-o C
    E -.-o C
    F -.-o C
    G -.-o C
    H -.-o C

As shown, you can use AsyncLocalStore to execute the async function and register a watcher to navigate to the AsyncResource. This method allows you to browse the AsyncResource using the executionAsyncId function without passing a FastifyRequest or AsyncLocalStore.

Usage

import fastify from 'fastify';
import { maeumAsyncContext, AsyncContainer } from '@maeum/async-context';
import { PrismaClient } from '@prisma/client';
import { executionAsyncId } from 'node:async_hooks';
import { fastifyRequestContext } from '@fastify/request-context';

AsyncContainer.bootstrap({ resourceTypes: ['request-id-tracker'] });

class TrackerAsyncResource {
  #tid: string;

  #lang: string | undefined;

  constructor(tid: string, lang: string | undefined, type?: string, triggerAsyncId?: number) {
    super(type ?? CE_SERVER_DEFAULT_VALUE.TRACKING_ID_AC, triggerAsyncId);

    this.#tid = tid;
    this.#lang = lang;
  }

  get tid() {
    return this.#tid;
  }

  get lang() {
    return this.#lang;
  }
}


const server = fastify({ logger: true });

server.regiger(fastifyRequestContext, {
  defaultStoreValues: (req) => ({ tid: req.id }),
  createAsyncResource: (req) => {
    const resource = new TrackerAsyncResource(
      req.id,
      req.headers['accept-language'],
      'request-id-tracker',
      executionAsyncId(),
    );
    AsyncContainer.it.setStore(executionAsyncId(), resource);
    return resource;
  },
});

server.get(async (req) => {
  console.log('id is same, ', req.id, (await AsyncContainer.getStore(executionAsyncId())).tid);
  const pet = await petSelectDao({ petId: req.query.id });
  return pet;
});

const prisma = new PrismaClient({
  log: [
    {
      emit: 'event',
      level: 'query',
    },
  ],
});

async function petSelectDao(petId: string) {
  console.log('id is same, ', req.id, (await AsyncContainer.getStore(executionAsyncId())).tid);
  return prisma.find({ id: petId });
}

// To get the request id in the event handler, you can use the AsyncContainer's getStore function to access the context
prisma.$on('query', (e) => {
  const store = AsyncContainer.getStore(executionAsyncId());
  console.log(store.id, e.query, e.params);
});

License

This software is licensed under the MIT.

Package Sidebar

Install

npm i @maeum/async-context

Weekly Downloads

48

Version

1.2.0

License

MIT

Unpacked Size

81.8 kB

Total Files

9

Last publish

Collaborators

  • jooni