简体   繁体   English

Hapi.js 中的 AsyncLocalStorage

[英]AsyncLocalStorage in Hapi.js

I trying to add trace id in async storage, onRequest.我试图在异步存储 onRequest 中添加跟踪 ID。 But in the handler, there is no stored data.但是在处理程序中,没有存储数据。 Why data is empty in handler?为什么处理程序中的数据为空? What am I do wrong?我做错了什么?

async local storage:异步本地存储:

const {AsyncLocalStorage} = require('async_hooks')
const asyncLocalStorage = new AsyncLocalStorage() 
module.exports = {
  asyncLocalStorage
}

setup:设置:

server.ext({
    type: 'onRequest',
    method(request, h) {
      return new Promise(resolve => {
        getLocalStorage().run({meta: {traceId: 'id'}}, () => {
          return resolve(h.continue)
        })
      })
    },
  })

handler:处理程序:

    {
    path: '/',
    method: 'GET',
    handler: (req) => {
      const data = asyncLocalStorage.getStore()
      //why data is undefined?
      return data;
    },
    options: {
      tags: ['api', 'Test'],
      description: "Test",
      auth: {
        strategy: 'jwt_user',
        scope: ['USER'],
      },
      response: {
        schema: testResponseSchema,
        modify: true,
        options: {
          stripUnknown: true,
          convert: true,
        },
      },
    },
  },

I was able to get it to work (note - I am still testing this) using a wrapper over the handler function like below.我能够使用处理程序 function 上的包装器使其正常工作(注意 - 我仍在测试它),如下所示。

Step 1: Create a file async-local-storage.js第 1 步:创建文件 async-local-storage.js

// async-local-storage.js

const { AsyncLocalStorage } = require('async_hooks')

module.exports = {
  asyncLocalStorage: new AsyncLocalStorage(),
}

Step 2: Create a wrapper for handler function第 2 步:为处理程序 function 创建包装器

// handle-request.js

const asyncLocalStorage = require('./async-local-storage').asyncLocalStorage

function handleRequest(handler) {
  return (req, h) => {
    const correlationId = req.headers['correlationId']
    return asyncLocalStorage.run({ correlationId : correlationId || 'Not set' }, async () => {
      return handler(req, h)
    })
  }
}

module.exports = {
  handleRequest,
}

Step 3: In each route, use the handleRequest wrapper.第 3 步:在每个路由中,使用handleRequest包装器。

// routes.js

const handleRequest = require('./handle-request').handleRequest
const myTestApiHandler = require('./myTestApiHandler').myTestApiHandler

module.exports = [
{
    method: 'GET',
    path: '/api/my-test-api',
    config: {
      handler: handleRequest(myTestApiHandler),
    },
  },
}]

Now, in myTestApiHandler we can get correlationId like below.现在,在myTestApiHandler中,我们可以获得如下所示的 correlationId。

// myTestApiHandler

const asyncLocalStorage = require('./async-local-storage').asyncLocalStorage

function myTestApiHandler(req, h) {
  const store = asyncLocalStorage.getStore();
  const correlationId = store.correlationId;
  ..
  ..
  
}

module.exports = {
  myTestApiHandler
}

The correlationId should also be available to any functions getting invoked from the myTestApiHandler function like logger etc. correlationId 也应该可用于从myTestApiHandler function 调用的任何函数,如记录器等。

Please refer official doc for AsyncLocalStorage for more details有关详细信息,请参阅AsyncLocalStorage的官方文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM