Skip to content
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

feat: expose withSpanAsync on NodeTracer #752 #1011

Closed

Conversation

vmarchaud
Copy link
Member

@vmarchaud vmarchaud commented May 2, 2020

This doens't work because of some bug inside the AsyncHookContextManager but i'm opening the PR in the mean time to get feedback on how we can accomplish this.

The main issue is that i need to use // @ts-ignore there since the withAsync is not exposed at the api level, don't know if we have other solutions here
WDYT ?

@vmarchaud vmarchaud self-assigned this May 2, 2020
@vmarchaud vmarchaud added question User is asking a question not related to a new feature or bug size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 2, 2020
@vmarchaud vmarchaud marked this pull request as draft May 2, 2020 15:04
@vmarchaud vmarchaud force-pushed the withasync-node-tracer branch 3 times, most recently from 0e3d36c to b794a08 Compare May 10, 2020 09:35
@vmarchaud vmarchaud requested a review from dyladan May 10, 2020 09:58
@dyladan dyladan added the API label May 12, 2020
@vmarchaud vmarchaud force-pushed the withasync-node-tracer branch from b794a08 to 3308204 Compare May 17, 2020 17:09
@vmarchaud vmarchaud requested a review from dyladan May 17, 2020 17:09
@vmarchaud
Copy link
Member Author

@dyladan I've changed the return type of withSpanAsync to void. I failed to find a type that would say that we return what U return (and i believe thats the point of the Awaited new type being working on in TS).

I don't think we should have the behavior to return the value returned by the callback too, the aim of the API isn't to pass value but to set a context, WDYT ?

@vmarchaud vmarchaud force-pushed the withasync-node-tracer branch from 3308204 to 07e7843 Compare May 17, 2020 17:13
@dyladan
Copy link
Member

dyladan commented May 18, 2020

@dyladan I've changed the return type of withSpanAsync to void. I failed to find a type that would say that we return what U return (and i believe thats the point of the Awaited new type being working on in TS).

I don't think we should have the behavior to return the value returned by the callback too, the aim of the API isn't to pass value but to set a context, WDYT ?

I think it is a very common use case that you want the return value of the called function. tracer.withAsync(() => getFromAPI());.

Think something like this should work?

<T extends () => any, U = ReturnType<T> extends Promise<infer V> ? V : ReturnType<T>>(context: Context, fn: T) => Promise<U>;

Or you could factor out the confusing typing

type Unpacked<T> = T extends Promise<infer U>
  ? U
  : T;

class Foo {
  async withAsync<T extends () => any, U = Unpacked<ReturnType<T>>>(context: Context, fn: T): Promise<U> {
    return fn();
  }
}

edit: you could force the function to be async too like this:

type Unpacked<T> = T extends Promise<infer U>
  ? U
  : T;

class Foo {
  async withAsync<T extends () => Promise<any>, U = Unpacked<ReturnType<T>>>(context: Context, fn: T): Promise<U> {
    return fn();
  }
}


#### withSpanAsync

The `NodeTracer` expose a method called `withSpanAsync` that allows you to set a current span in the context of a `async` function. This previously was a problem with `withSpan` because its synchronous behavior, read about that in [this issue](https://github.com/open-telemetry/opentelemetry-js/issues/752).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this functionality be integrated into the existing withSpan method by detecting if a promise has been passed back? Not sure if I missed the discussion around this while catching up, but the ergonomics would be better if you didn't have to change the method call when you swap a callback in withSpan to an async function.

You should be able to call fn, and clear the context in a .finally (or then/catch pair) off the return value. I would imagine the context propagation for the interstitial promises could be handled by async_hooks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has been a lot of discussion around this and we decided to keep them separate for now. This decision came down to performance impact and the higher likelihood for subtle bugs using the more complex async mechanism.

@vmarchaud vmarchaud force-pushed the withasync-node-tracer branch from 07e7843 to 9e66e40 Compare May 23, 2020 14:17
@codecov
Copy link

codecov bot commented May 23, 2020

Codecov Report

Merging #1011 into master will decrease coverage by 21.09%.
The diff coverage is n/a.

@@             Coverage Diff             @@
##           master    #1011       +/-   ##
===========================================
- Coverage   94.98%   73.88%   -21.10%     
===========================================
  Files         238       71      -167     
  Lines        9085     1570     -7515     
  Branches      822      271      -551     
===========================================
- Hits         8629     1160     -7469     
+ Misses        456      410       -46     
Impacted Files Coverage Δ
packages/opentelemetry-core/test/utils/url.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...ckages/opentelemetry-core/test/platform/id.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...s/opentelemetry-core/src/platform/node/sdk-info.ts 0.00% <0.00%> (-100.00%) ⬇️
...pentelemetry-core/src/platform/node/performance.ts 0.00% <0.00%> (-100.00%) ⬇️
...pentelemetry-core/test/internal/validators.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...ntelemetry-core/test/trace/NoRecordingSpan.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...telemetry-core/test/platform/hex-to-base64.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...elemetry-core/test/trace/spancontext-utils.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...lemetry-core/test/trace/ProbabilitySampler.test.ts 0.00% <0.00%> (-100.00%) ⬇️
...try-core/test/trace/fixtures/test-package/index.js 0.00% <0.00%> (-100.00%) ⬇️
... and 183 more

@vmarchaud
Copy link
Member Author

I've rebased on #1099 to run tests with it (and it works). waiting for it to be merged to set this one as ready for review

@vmarchaud
Copy link
Member Author

As a solution has been to fix .with in #1099, we dont need this anymore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question User is asking a question not related to a new feature or bug size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to rely on AsyncHooksScopeManager when wrapping async functions
3 participants