Skip to content
This repository was archived by the owner on Jan 21, 2026. It is now read-only.

feat: allow "disabling" cls, and relax requirements for creating root spans#728

Merged
kjin merged 11 commits intogoogleapis:masterfrom
kjin:cls-new-4
Apr 25, 2018
Merged

feat: allow "disabling" cls, and relax requirements for creating root spans#728
kjin merged 11 commits intogoogleapis:masterfrom
kjin:cls-new-4

Conversation

@kjin
Copy link
Copy Markdown
Contributor

@kjin kjin commented Apr 19, 2018

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 to runInRootSpan(spanConfig, (rootSpan) => { /*...*/ }) will see all child spans created under that root until rootSpan.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:

  • If there is no root context in the current continuation, create a new root span, and a corresponding root context in the current continuation.
  • If there is a root context in the current continuation, do not create a new root span.
  • When a root span is ended, clear the root context in the current continuation. (This is the new change)

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.

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Apr 19, 2018
@kjin kjin force-pushed the cls-new-4 branch 2 times, most recently from 248e332 to 6693f8a Compare April 19, 2018 18:26
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 19, 2018

Codecov Report

Merging #728 into master will increase coverage by 0.17%.
The diff coverage is 89.65%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
src/cls/async-listener.ts 100% <ø> (ø) ⬆️
src/config.ts 100% <ø> (ø) ⬆️
src/cls/universal.ts 92.3% <100%> (+15.38%) ⬆️
src/trace-api.ts 94.44% <100%> (+0.06%) ⬆️
src/index.ts 83.72% <83.33%> (+0.38%) ⬆️
src/cls.ts 94.23% <90%> (+0.75%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update edb8135...035b045. Read the comment docs.

@ofrobots
Copy link
Copy Markdown
Contributor

Is RootSpan synonymous with a Context now?

Comment thread src/cls.ts Outdated
if (asyncHooksAvailable) {
this.CLSClass = AsyncHooksCLS;
this.rootSpanStackOffset = 4;
break;

This comment was marked as spam.

Comment thread src/cls/async-listener.ts Outdated
}

clearContext(): void {
if (this.getContext() !== this.defaultContext) {

This comment was marked as spam.

This comment was marked as spam.

Comment thread 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.

Comment thread src/config.ts Outdated
* 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.

This comment was marked as spam.

googleGax = require('./fixtures/google-gax0.16');
});

after(() => {

This comment was marked as spam.

This comment was marked as spam.

Comment thread 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.

Comment thread 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.

Comment thread 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.

Comment thread src/config.ts Outdated
* 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.

Comment thread src/index.ts Outdated
interface TopLevelConfig {
enabled: boolean;
logLevel: number;
clsMechanism: 'none'|'auto';

This comment was marked as spam.

Comment thread 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.

Comment thread src/trace-api.ts
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.

@kjin
Copy link
Copy Markdown
Contributor Author

kjin commented Apr 20, 2018

Summary of changes in commit order:

  • I added the TraceCLSMechanism enum. It is not user-facing.
  • Various other changes to address comments.
  • Instead of clearing context, we instead simply explicitly allow root spans to be created when a root span context already exists, but that root span is ended, while still warning if child spans are created under those same conditions. This means that clearContext is now unnecessary and has been removed.

Comment thread src/cls.ts
* 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.

This comment was marked as spam.

Copy link
Copy Markdown
Contributor

@jinwoo jinwoo left a 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.

Copy link
Copy Markdown
Contributor

@ofrobots ofrobots left a comment

Choose a reason for hiding this comment

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

lgtm w/ nit.

Comment thread src/span-data.ts Outdated
import * as crypto from 'crypto';
import * as util from 'util';

import {cls} from './cls';

This comment was marked as spam.

@kjin kjin merged commit 5d000e9 into googleapis:master Apr 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

cla: yes This human has signed the Contributor License Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants