【问题标题】:AsyncLocalStorage in Hapi.jsHapi.js 中的 AsyncLocalStorage
【发布时间】:2021-10-06 07:43:29
【问题描述】:

我尝试在异步存储 onRequest 中添加跟踪 ID。但是在处理程序中,没有存储数据。为什么处理程序中的数据为空?我做错了什么?

异步本地存储:

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

设置:

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

处理程序:

    {
    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,
        },
      },
    },
  },

【问题讨论】:

  • 好问题,我正在努力实现同样的目标,但出于某种原因,它只是在表达上有效,而使用 HAPI 似乎是个大问题。

标签: node.js hapijs asyncstorage hapi


【解决方案1】:

我能够使用下面的处理程序函数的包装器使其工作(注意 - 我仍在测试这个)。

第 1 步:创建文件 async-local-storage.js

// async-local-storage.js

const { AsyncLocalStorage } = require('async_hooks')

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

第 2 步:为处理函数创建包装器

// 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,
}

第 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),
    },
  },
}]

现在,在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
}

correlationId 也应该可用于从 myTestApiHandler 函数调用的任何函数,例如记录器等。

更多详情请参考AsyncLocalStorage官方文档

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多