Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customizable AsyncResource.type and create-resource #172

Closed
2 tasks done
imjuni opened this issue Dec 11, 2023 · 2 comments · Fixed by #173
Closed
2 tasks done

Customizable AsyncResource.type and create-resource #172

imjuni opened this issue Dec 11, 2023 · 2 comments · Fixed by #173

Comments

@imjuni
Copy link
Contributor

imjuni commented Dec 11, 2023

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

  • pass AsyncResource factory
  • pass AsyncResource.type

index.js

fastify.addHook(hook, (req, res, done) => {
    const defaultStoreValues = hasDefaultStoreValuesFactory
      ? opts.defaultStoreValues(req)
      : opts.defaultStoreValues

    asyncLocalStorage.run({ ...defaultStoreValues }, () => {
      const asyncResource =
        opts.createResource != null
          ? opts.createResource(req, requestContext)
          : new AsyncResource(
              opts.resourceType != null ? opts.resourceType : 'fastify-request-context',
            )
      req[asyncResourceSymbol] = asyncResource
      asyncResource.runInAsyncScope(done, req.raw)
    })
  })

Motivation

When using TypeORM or Prisma, logging can be customized: there is a way to use the triggerId of the AsyncContext to find the AsyncResource in order to pass the request.id to the logger. This would require either changing the type of the AsyncResource, or a factory that allows developers to create AsyncResources in whatever form the developers want.

Example

// async_hooks.createHook
watcher
      .setupInitHook()
      .setupBeforeHook()
      .setupAfterHook()
      .setupDestroyHook()
      .setupPromiseResolveHook()
      .start()
      .on(
        'INIT',
        ({
          asyncId,
          type,
          resource,
          triggerAsyncId,
        }: {
          asyncId: number;
          type: string;
          triggerAsyncId: number;
          executionAsyncId: number;
          resource: object;
        }) => {
          idMap.set(asyncId, triggerAsyncId);

          // customized AsyncResource.type
          if (type === 'fastify-request-context' || type === 'tid-async-resource') {
            resourceMap.set(asyncId, resource);
          }
        },
      )
      
// getStore
getStore<T = AsyncResource>(asyncId: number) {
    let resource: object | undefined = resourceMap.get(asyncId);

    if (resource != null) {
      return resource as T;
    }

    let id = idMap.get(asyncId);
    let sentinel = 0;

    while (id != null && sentinel < 1000) {
      resource = resourceMap.get(id);

      if (resource != null) {
        return resource as T;
      }

      id = idMap.get(id);
      sentinel += 1;
    }

    return undefined;
  }
@kibertoad
Copy link
Member

Would you be open to send a PR for this? Please remember to include tests and documentation!

@imjuni
Copy link
Contributor Author

imjuni commented Dec 14, 2023

I added this feature by #173, but the test fails. This feature is expected to enhance issue #153 as well.

@Eomm Eomm linked a pull request Dec 18, 2023 that will close this issue
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants