-
Notifications
You must be signed in to change notification settings - Fork 821
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(context): implement withAsync #752 #926
Conversation
1184e68
to
081528d
Compare
Codecov Report
@@ Coverage Diff @@
## master #926 +/- ##
==========================================
+ Coverage 94.95% 95.03% +0.07%
==========================================
Files 210 210
Lines 8571 8705 +134
Branches 772 776 +4
==========================================
+ Hits 8139 8273 +134
Misses 432 432
|
packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts
Outdated
Show resolved
Hide resolved
As usual it's hard to follow AsyncHooks, in special in combination with Maybe we should add some more tests with mixed of sync/async callbacks? This is for sure not blocking and can be done in separate PRs. But in general I have the feeling more scenarios in the tests helps to understand who it works even if the test coverage doesn't increase. |
@Flarna Totally agree, i believe its in the scope of that PR so i will add few more cases |
I've added some, the only counter intuitive one would be: it('should correctly restore scope', done => {
const scope1 = '1' as any;
const scope2 = '2' as any;
contextManager.with(scope1, () => {
assert.strictEqual(contextManager.active(), scope1);
contextManager
.withAsync(scope2, async () => {
assert.strictEqual(contextManager.active(), scope2);
})
.then(() => {
assert.strictEqual(contextManager.active(), scope1);
return done();
});
// in this case the current scope is 2 since we
// didnt waited the withAsync call
// however some would expect that the scope should be 1
assert.strictEqual(contextManager.active(), scope2);
});
}); I would argue that even though its counter intuitive, its working as intented. One more reason for developers to avoid floating promises in their code. |
packages/opentelemetry-context-async-hooks/test/AsyncHooksContextManager.test.ts
Outdated
Show resolved
Hide resolved
packages/opentelemetry-context-async-hooks/test/AsyncHooksContextManager.test.ts
Outdated
Show resolved
Hide resolved
packages/opentelemetry-context-async-hooks/test/AsyncHooksContextManager.test.ts
Show resolved
Hide resolved
@Flarna Addressed your comments once again ! |
packages/opentelemetry-context-async-hooks/test/AsyncHooksContextManager.test.ts
Show resolved
Hide resolved
@open-telemetry/javascript-approvers Need some reviews here ! |
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.
lgtm, however I would suggest to combine the body of those 2 functions
packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts
Show resolved
Hide resolved
On the performance side, i've tested
and with this branch (in its current form):
|
packages/opentelemetry-context-zone-peer-dep/src/ZoneContextManager.ts
Outdated
Show resolved
Hide resolved
9cc34de
to
cc6fcb4
Compare
I've decided to remove |
I think it's a good idea to only surface it as part of the SDK not the API. That way, we're not locking ourselves into supporting it everywhere when that may not be possible. Do we also want to consider marking it as experimental in some way? Not sure if there is some tsdoc |
@dyladan I would prefer to mark as experimental the |
@mayurkale22 If you don't have any blocker on your side could we merge this one after the release so i can make the next PR to add |
Just a drive by comment in case it's useful - Node natively includes experimental support for context between async calls. I'm unable to link directly, but its under the "Experimental Async Local Storage API" heading here: https://medium.com/@nodejs/node-js-version-14-available-now-8170d384567e I'll paste in the paragraph below
I'm thinking this project is the perfect one to "try out this API and give us feedback" 😀 You might already know about this of course, but I tried searching this repo for mentions without finding it, so thought I'd drop a comment at least |
I took @dyladan initial work from his branch and tried to debug the following test case which wasnt working:
Note: i will refer to
scope
when speaking about javascript context (this
) andcontext
when refering about our implementation.The things to know when working with
async
/await
is that V8 is essentially wraping the code that follow theawait
inside a new scope. Theasync_hooks
API allows us to track the creation of these new scopes so we can associate the newly created scopes ids with the context available at the time of their creation.So in the test case, where i placed the
// HERE
comment, we are in a new scope that should contains the correct context because as said above we associated scope and their corresponding context. The problem is that the context is associated with a given scope change. In our case:The fix is pretty simple in theory, which map a given javascript context to a pointer that hold a reference to a context.
Since the only reference that exists in javascript are object, i added a simple
Reference
class which is only used to hold a reference to the context.I'm pretty sure that my explaination is not clear so feel free to ask questions if you have any.
Also, i will make a separate PR for adding
withAsync
on the tracers. I will believe this one is already quite hard to review to not add more code !