opentracing-javascript
opentracing-javascript copied to clipboard
ScopeManager
Addresses #112
See https://github.com/opentracing/specification/blob/f7ca62c9/rfc/scope_manager.md
Continuation passing style
I first tried adhering to the draft RFC (somewhat working code), but it got clumsy, particularly for the Zone.js implementation. Just about every JS continuation library uses continuation passing style (Zone.js, Node.js domains, continuation-local-storage, etc.), and I believe it's the correct choice. Plus, the existing RFC IMO has a lot of ambiguity for the implementer. I added my findings to https://github.com/opentracing/specification/issues/126.
Support
Unfortunately, there just isn't a great universal, out-of-the-box CLS solution.
There are two things that can be addressed by CLS: native async syntax (async/await), and common APIs (e.g. fs.readFile).
The are a surprising number of issues with current solutions. https://github.com/othiym23/node-continuation-local-storage is widely used, but can't be used with async/await which in 2018 is increasingly common. https://github.com/gms1/node-async-context can be, but (so far) doesn't have a lot of adoption and requires Node 8+. https://github.com/angular/zone.js/ has related TC39 proposal, but it's been stalled for two years.
In the end, the JS community has not figured out CLS (yet). I added a few implementations with very minimal dependencies that between them have fairly broad coverage. (See README.md for details.)
Implementations:
- AsyncHookSpanManager - uses Node.js async_hooks
- AsyncWrapSpanManager - uses async-hook-jl which uses Node.js AsyncWrap
- ZoneSpanManager - uses Zone.js
In the future, I expect the situation to improve. But this seems a good start, these wrappers are rather simple (~50 lines each).
Coverage increased (+1.5%) to 90.019% when pulling 71e124fc7ed145dee01338479b1d05f3ba9fd785 on rivethealth:pauldraper/scope-manager into 0f145548a8c26f7761d33d274e5988e69ce2251e on opentracing:master.
Update: looks like https://github.com/RisingStack/jaeger-node and https://github.com/RisingStack/opentracing-auto use async_hooks. I believe that would be the most common method of CLS, since if you use Node.js and a recent version of it, it has the fewest drawbacks.