-
Notifications
You must be signed in to change notification settings - Fork 171
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
Spans are mixed on concurrent async calls on a Hapi server #483
Comments
Thanks for this @scabfos, as you may know zipkin is a volunteering project and reporting an issue with a breaking example is truly appreciated. I managed to make it work but I am not sure how to proceed in terms of implementing the fix. The main issue here is that hapi instrumentation works in terms of return function zipkinExpressMiddleware(req, res, next) {
...
tracer.scoped(() => {
...
next()
})
} This means that everything in server.route({
method: 'GET',
path: '/',
config: {
pre: [
{
method: () => {
return doCall()
},
assign: 'users',
}, into server.route({
method: 'GET',
path: '/',
config: {
pre: [
{
method: (req) => {
return tracer.scoped(function() {
tracer.setId(req._trace_id) // reasigning the traceId in the scope from https://github.com/openzipkin/zipkin-js/blob/master/packages/zipkin-instrumentation-hapi/src/hapiMiddleware.js#L28
return doCall()
})
},
assign: 'users',
}, Then everything works as expected. I am not necessarily an expert in JS but one alternative I see here is that we wrap the whole I am friendly pinging @hueniverse to see if there is a way to wrap the |
what @jcchavezs said makes sense. We cannot effectively instrument a listener model, unless there is shared state between the listeners. For example, if it is 100% the case that onX is followed by onY or onZ, and between onX and onY or onZ, user code is executed.. you can use tracer.setId(span) in onX, and revert it in onX or onY. |
It looks like there is a plugins object where plugins can put request state they need (though this is JavaScript, we could just set any attribute if we really wanted :-) ) https://github.com/hapijs/hapi/blob/master/API.md#-requestplugins I think this should give the shared state between listeners we need, can't we put the trace context in? |
one thing to note about the state issue is we are talking about the state
around scope. ex which scope to revert to.. ex tracer.setId is similar to
java currenttracecontext.newScope
anyway sounds like we have options which is good!
…On Sun, Feb 9, 2020, 8:25 PM Anuraag Agrawal ***@***.***> wrote:
It looks like there is a plugins object where plugins can put request
state they need (though this is JavaScript, we could just set any attribute
if we really wanted :-) )
https://github.com/hapijs/hapi/blob/master/API.md#-requestplugins
I think this should give the shared state between listeners we need, can't
we put the trace context in?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#483?email_source=notifications&email_token=AAAPVV4NKV4FWPOWI3T7GT3RCDJLXA5CNFSM4KRNCIA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELHF2LI#issuecomment-583949613>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAPVV3YJVDCJEB2ZAJ3CULRCDJLXANCNFSM4KRNCIAQ>
.
|
@adriancole we currently do that but id does not work when using promises (this is what I noticed) because you can't wrap the actual handler execution with a scope.
@anuraaga we do that already, see https://github.com/openzipkin/zipkin-js/blob/master/packages/zipkin-instrumentation-hapi/src/hapiMiddleware.js#L28
@adriancole I am not sure about this statement. As I said the problem is that eventhough we set the |
hard for me to drive-by recommend anything. I mainly meant that |
Found that lifecycle methods are called in order here https://github.com/hapijs/hapi/blob/master/lib/request.js#L455 Indeed, because the result is always That being said, it seems that hapi supports multiple server decorators since 17.1.0 Looking at our instrumentation we wanted to use this but couldn't due to the limit of one. Now that it isn't an issue, can we use that to decorate handlers? Not sure if we have a min version requirement that doesn't work with that though.
|
@anuraaga @adriancole I don't see how the decorate could help us with the wrapping. If the intention is that we can override the I opened an issue in hapi repo, I hope we can get better insights in there: hapijs/hapi#4049 |
What does it mean to wrap a handler or a pre? What happens when code runs inside the |
I am encountering this limitation also when trying to use Continuation Local Storage to set some correlation id (similar to zipkin). I believe this might have been possible before the toolkit signals were added to the lifecycle methods signature (<=16), as one could have done something like this on the onRequest listener:
|
By the way we are currently decorating all the handlers in one go as we start the server:
And the loggingContextDecorator does something like:
|
We use zipkin-js to observe our Hapi server and its dependencies and we noticed that when we get multiple concurrent calls, some of the spans are getting assigned to the wrong traces.
We were working on this issue with @jcchavezs and we created a PR with an example to prove with a simple Hapi project that this is in fact happening.
As you see in the images, when doing multiple concurrent calls, spans are getting assigned to the wrong one.
Steps to reproduce
docker run -d -p 9411:9411 openzipkin/zipkin
yarn && node index.js
ab -c10 -n10 http://127.0.0.1:3000/
If you have any idea or questions you can reach us at @lussn @alexfdz @javigomez
Thank you!
The text was updated successfully, but these errors were encountered: