puzpuzpuz/cls-rtracer

Why does the Hapi plugin implementation use enterWith() instead of run()?

ao10 opened this issue · 3 comments

ao10 commented

Hi, I had a question on the implementation for the Hapi plugin. I noticed that for the rest of the other framework middleware/plugins you use AsyncLocalStorage.run() but for the Hapi plugin enterWith() is used instead? Why is that and what is it about Hapi specifically that it had to be done this way?

From the Node docs

run() should be preferred over enterWith() unless there are strong reasons to use the latter method.

https://nodejs.org/api/async_context.html#asynclocalstorageenterwithstore

Thank you

Hello,

That's because of the plugin API provided by Hapi in the form of multiple hooks. There is simply no single place where you could run ALS.run() (or, at least, that's how it used to be at the time when I was writing that code), so that's why cls-rtracer uses a low-level, less safe ALS API.

BTW Koa v1 middleware also uses ALS.enterWith():

cls-rtracer/src/rtracer.js

Lines 166 to 191 in 2745858

const koaV1Middleware = ({
useHeader = false,
headerName = 'X-Request-Id',
requestIdFactory = uuidv1,
echoHeader = false
} = {}) => {
return function * (next) {
let requestId
if (useHeader) {
requestId = this.request.headers[headerName.toLowerCase()]
}
requestId = requestId || requestIdFactory(this.request)
if (echoHeader) {
this.response.set(headerName, requestId)
}
als.enterWith(requestId)
try {
wrapHttpEmitters(this.req, this.res)
yield next
} finally {
als.enterWith(undefined)
}
}
}

The reason for Koa v1 is different - it uses generators.

Hopefully the above reply answers your question. Closing this one for now.

ao10 commented

Thank you!