-
Notifications
You must be signed in to change notification settings - Fork 108
Scope #117
base: master
Are you sure you want to change the base?
Scope #117
Conversation
2 similar comments
} | ||
|
||
protected _active(): Span | null { | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should a no-op span be returned here instead? It would have the benefit of not breaking the app if a user disables the tracer in situations where the code assumes there is always a span available for a specific scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conventionally, active
returns either the current Scope or null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand what this PR enables a user, as it doesn't seem to actually implement any continuation passing through e.g. async hooks. It seems like there is still manual code needed to propagate the spans, so there doesn't seem to be an improvement over the status quo. The PR description says it's up to vendors, but why should e.g. Jaeger and Lightstep have to implement these?
It also seems to favour specific async representations - Node EventEmitters and Promises, but what about usage in the browser with EventTargets, or Observables, Genertors, AsyncIterables, etc?
@@ -0,0 +1,20 @@ | |||
declare module 'emitter-listener' { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you submit this to DefinitelyTyped instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but in the meantime it should not block this PR.
* boolean to indicate that the childOf option should not implicitly be set | ||
* to the currently active span. | ||
*/ | ||
ignoreActiveSpan?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this defaults to false
, is this a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's breaking in that a span may end up with a parent where there were no parent before. I personally don't mind either way, but according to the spec it should be false by default.
"module": "commonjs", | ||
"baseUrl": ".", | ||
"paths": { | ||
"*": ["src/@types/*"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be done with typeRoots
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not very familiar with TypeScript. Could you explain the difference?
@@ -2,19 +2,24 @@ | |||
"compilerOptions": { | |||
"target": "es5", | |||
"lib": [ | |||
"es5", | |||
"es2015", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why this is a breaking change? My understanding is that this is necessary to support using Promise
, and doesn't change the output, only the linting.
src/scope.ts
Outdated
* | ||
* @returns {any} The provided function bound to the span. | ||
*/ | ||
bind<T>(fn: ScopeCallback<T>, span?: Span | null): ScopeCallback<T>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this overload throw away the types of the parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate? I haven't done a lot of TypeScript so any help with typing is appreciated.
@felixfbecker Thanks for the review!
Right now it's not possible for vendors to implement an OpenTracing scope manager since there is no interface, meaning that right now every vendor has completely different APIs and implementations. This PR enables vendors to start moving to the official API and to eventually contribute this repo. It also enables the implementations to be compatible with OpenTracing by exposing official interfaces. I focused on only the minimum required functionality for this PR, and then we can iterate.
The idea is to eventually have all the implementations in sub-projects of this repo. For example, I have an
This is why I made the tl;dr This PR is the minimum functionality required so that vendors can start implementing scope managers compatible with OpenTracing. We can then iterate with future PRs to have the different implementations live directly in this repo. |
Could you link an example of a vendor API for scope management? I've only used Jaeger and LightStep which don't have one afaik
Do you mean just the new code in this PR? Because I am using the current version of
What do you mean by "extensible"? Being a method of a class it seems rather sealed to me? It would also mean that even if I don't use e.g. Observables in my project, the code for supporting Observables cannot be tree-shaked. So far I've used simple helper functions to manage spans: https://sourcegraph.com/github.com/sourcegraph/javascript-typescript-langserver@64d9479c89039290f9aa530547bf2845e6d33c49/-/blob/src/tracing.ts#L35 |
I know at least New Relic, Elastic APM, Stackdriver Trace and OpenCensus each do it their own way. I don't know if they have OpenTracing compatibility however, especially since having your own scope manager automatically makes you partially incompatible with OpenTracing right now.
I mean that we at Datadog don't currently support the browser, which is why I focused on Node for now. As mentioned however, additional browser specific functionalities can be added in future iterations.
Right now by simply implementing the
That could be optimized eventually by adding a way to register additional binding methods externally, but for now I only included the functionalities that would be required for every single vendor meaning that this is currently a non-issue. It's also worth noting that each additional method is usually around 10 lines of code, so IMHO the pros outweighs the cons. |
The problem with this is that vendors can only implement existing methods, not add new ones. This is why I hide the different implementations behind a single method. |
Removed the implementation for @austinlparker @felixfbecker Can you take another look? |
@yurishkuro What should be done with this PR? Should we close it? There is a clear lack of interest to merge this feature and OpenTracing is scheduled to be deprecated by the upcoming merge of OpenTracing and OpenCensus. |
I would keep it, if only as a reference. You're correct, it's hard to allocate resources to this given the OT/OC merger and the work on the new libs. It would be great if you could participate in those, and perhaps transfer this PR into the new project (once it's set up). |
I will definitely keep an eye open for the new project and port the scope manager if needed. @yurishkuro What is the best place right now to track the current status of the merger? Any way I can help for JavaScript? |
Updates / schedules are being posted on Medium/Twitter. https://medium.com/opentracing/a-roadmap-to-convergence-b074e5815289 The work on Javascript hasn't started yet. @tedsuo thoughts? Do we plan to kick off other languages before Java API is solidified (naming, etc.)? |
I would argue it’s probably best to do at least 1 dynamic interpreted language at the same time as Java, as in my experience APIs designed solely for Java tend to ignore fundamental differences with other languages. This also applies to terminology and async patterns. In general I find Python and JavaScript to be good candidates to find such discrepancies. |
This PR implements the scope manager specification using continuation passing style as discussed in opentracing/specification#126 and #112.
The implementation assumes a scope is always available and thus doesn't require an actual scope manager. The scope itself handles creating child scopes and activating spans.
An utility method for binding different types of callback constructs has been included as well. Right now it supports callback functions, promises and event emitters, but the API is flexible and could be extended with additional constructs eventually.
For now only a no-op implementation is provided, and the actual implementation is up to the vendors. In the future, implementations should live in this repository since this is a cross-cutting concern that is always handled the same way.