-
Notifications
You must be signed in to change notification settings - Fork 103
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
fix: (observability) make async/await correctly work by setting initial AsyncHooksManager #2147
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -26,7 +26,9 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Span, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SpanStatusCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trace, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ROOT_CONTEXT, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
INVALID_SPAN_CONTEXT, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SpanAttributes, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
TimeInput, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -93,6 +95,30 @@ interface traceConfig { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
const SPAN_NAMESPACE_PREFIX = 'CloudSpanner'; // TODO: discuss & standardize this prefix. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export {SPAN_NAMESPACE_PREFIX, traceConfig}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AsyncHooksContextManager, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} = require('@opentelemetry/context-async-hooks'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* This function ensures that async/await functions correctly by | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* checking if context.active() returns an invalid/unset context | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* and if so, sets a global AsyncHooksContextManager. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @odeke-em I generated this documentation using AI, please review once more. But we need a more structured documentation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some of this AI generated documentation is not correct like
it's nothing about manually managing context but setting a global context manager. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @surbhigarg92 the generated AI comments instead just is listing out what the function does but not really why and the purpose of the code which is to check if there was any already set contextManager and if not, set one. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function ensureInitialContextManagerSet() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (context.active() === ROOT_CONTEXT) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// If no active context was set previously, trace context propagation cannot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// work correctly with async/await for OpenTelemetry and they acknowledge | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// this fact per https://opentelemetry.io/docs/languages/js/context/#active-context | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// but we shouldn't make our customers have to invasively edit their code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// nor should they be burdened about these facts, their code should JUST work. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Please see https://github.com/googleapis/nodejs-spanner/issues/2146 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context.disable(); // Firstly disable any prior contextManager. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const contextManager = new AsyncHooksContextManager(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextManager.enable(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context.setGlobalContextManager(contextManager); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* startTrace begins an active span in the current active context | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* and passes it back to the set callback function. Each span will | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -111,6 +137,8 @@ export function startTrace<T>( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
config = {} as traceConfig; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ensureInitialContextManagerSet(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return getTracer(config.opts?.tracerProvider).startActiveSpan( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SPAN_NAMESPACE_PREFIX + '.' + spanNameSuffix, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{kind: SpanKind.CLIENT}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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.
Use a better name for this. If you are testing "async/await" use name like
Observability tests with async/await
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'd highly encourage keeping such a section for known and fixed regressions with isolated test cases, otherwise eventually we'll just have a pile up of test cases that we don't have a single reference to.
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 the section in which we shall be inserting all regression tests and bug fixes.
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 tweaked it, please take a look.