-
Notifications
You must be signed in to change notification settings - Fork 98
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: allow "disabling" cls, and relax requirements for creating root spans #728
Conversation
248e332
to
6693f8a
Compare
Codecov Report
@@ Coverage Diff @@
## master #728 +/- ##
==========================================
+ Coverage 90.74% 90.92% +0.17%
==========================================
Files 30 30
Lines 1556 1564 +8
Branches 304 302 -2
==========================================
+ Hits 1412 1422 +10
+ Misses 61 59 -2
Partials 83 83
Continue to review full report at Codecov.
|
Is |
src/cls.ts
Outdated
if (asyncHooksAvailable) { | ||
this.CLSClass = AsyncHooksCLS; | ||
this.rootSpanStackOffset = 4; | ||
break; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/cls/async-listener.ts
Outdated
@@ -69,9 +69,15 @@ export class AsyncListenerCLS<Context extends {}> implements CLS<Context> { | |||
this.getNamespace().set(AsyncListenerCLS.ROOT_CONTEXT_KEY, value); | |||
} | |||
|
|||
clearContext(): void { | |||
if (this.getContext() !== this.defaultContext) { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/config.ts
Outdated
/** Available configuration options. */ | ||
export interface Config { | ||
/** | ||
* The context propagation mechanism to use. The following options are |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/config.ts
Outdated
@@ -166,6 +178,7 @@ export interface Config { | |||
* user-provided value will be used to extend the default value. | |||
*/ | |||
export const defaultConfig = { | |||
clsMechanism: 'auto' as ContextPropagationMechanism, |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
trace.setPluginLoader(); | ||
trace.start(); | ||
googleGax = require('./fixtures/google-gax0.16'); | ||
}); | ||
|
||
after(() => { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/cls.ts
Outdated
this.logger.error( | ||
'TraceCLS#constructor: The specified CLS mechanism', | ||
`[${config.mechanism}] was not recognized.`); | ||
throw new Error(`CLS mechanism [${config.mechanism}] is invalid.`); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/cls.ts
Outdated
default: | ||
this.logger.error( | ||
'TraceCLS#constructor: The specified CLS mechanism', | ||
`[${config.mechanism}] was not recognized.`); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/cls/async-listener.ts
Outdated
runWithNewContext<T>(fn: Func<T>): T { | ||
return this.getNamespace().runAndReturn(() => { | ||
this.setContext(this.defaultContext); | ||
this.clearContext(); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/config.ts
Outdated
@@ -166,6 +178,7 @@ export interface Config { | |||
* user-provided value will be used to extend the default value. | |||
*/ | |||
export const defaultConfig = { | |||
clsMechanism: 'auto' as ContextPropagationMechanism, |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/index.ts
Outdated
@@ -56,6 +56,7 @@ for (let i = 0; i < filesLoadedBeforeTrace.length; i++) { | |||
interface TopLevelConfig { | |||
enabled: boolean; | |||
logLevel: number; | |||
clsMechanism: 'none'|'auto'; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/index.ts
Outdated
.enable(); | ||
const m = config.clsMechanism; | ||
const clsConfig: Forceable<TraceCLSConfig> = { | ||
mechanism: m === 'auto' ? (useAH ? 'async-hooks' : 'async-listener') : m, |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/trace-api.ts
Outdated
options.name}] because root span [${ | ||
rootSpan.span.name}] was already closed.`); | ||
return UNCORRELATED_SPAN; | ||
} |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Summary of changes in commit order:
|
* An enumeration of the possible mechanisms for supporting context propagation | ||
* through continuation-local storage. | ||
*/ | ||
export enum TraceCLSMechanism { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
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.
Chatted offline. Using a string enum sounds good to me when their values may come directly from user configs in the future.
LGTM once CI passes.
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 w/ nit.
src/span-data.ts
Outdated
@@ -17,6 +17,7 @@ | |||
import * as crypto from 'crypto'; | |||
import * as util from 'util'; | |||
|
|||
import {cls} from './cls'; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Fixes #719
This PR introduces a new config option
clsMechanism
that can either be set to'none'
or'auto'
(and defaults to the latter, preserving the current behavior). Setting it to'none'
effectively treats the entire application as sharing the same root context, so any code running subsequent torunInRootSpan(spanConfig, (rootSpan) => { /*...*/ })
will see all child spans created under that root untilrootSpan.endSpan()
is called.The
'none'
CLS mechanism is at odds with the previous limitation that there may only be one root span per context, so this PR also changes behavior so that when a root span ends, context is cleared. As a result, this code path should now never be executed, so I have removed it.The new semantics for creating root spans is as follows:
Note that the "current continuation" in the first and third bullet points may not be the same continuation, even if the root spans mentioned are the same. It is still OK to clear the root context in the current continuation (as stated in the third bullet point) because there was none to begin with.