Skip to content

Commit

Permalink
chore: use interface for context types (#1515)
Browse files Browse the repository at this point in the history
  • Loading branch information
dyladan authored Sep 21, 2020
1 parent 3bc4d57 commit 75ae34c
Show file tree
Hide file tree
Showing 26 changed files with 265 additions and 260 deletions.
4 changes: 2 additions & 2 deletions packages/opentelemetry-api/src/api/propagation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class PropagationAPI {
public inject<Carrier>(
carrier: Carrier,
setter: SetterFunction<Carrier> = defaultSetter,
context = contextApi.active()
context: Context = contextApi.active()
): void {
return this._getGlobalPropagator().inject(context, carrier, setter);
}
Expand All @@ -90,7 +90,7 @@ export class PropagationAPI {
public extract<Carrier>(
carrier: Carrier,
getter: GetterFunction<Carrier> = defaultGetter,
context = contextApi.active()
context: Context = contextApi.active()
): Context {
return this._getGlobalPropagator().extract(context, carrier, getter);
}
Expand Down
7 changes: 6 additions & 1 deletion packages/opentelemetry-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ export {
INVALID_SPAN_CONTEXT,
} from './trace/spancontext-utils';

export { Context } from '@opentelemetry/context-base';
export {
Context,
ROOT_CONTEXT,
createContextKey,
ContextManager,
} from '@opentelemetry/context-base';

import { ContextAPI } from './api/context';
/** Entrypoint for context API */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { Context } from '@opentelemetry/context-base';
import { Context, ROOT_CONTEXT } from '@opentelemetry/context-base';
import * as asyncHooks from 'async_hooks';
import { AbstractAsyncHooksContextManager } from './AbstractAsyncHooksContextManager';

Expand All @@ -35,7 +35,7 @@ export class AsyncHooksContextManager extends AbstractAsyncHooksContextManager {
}

active(): Context {
return this._stack[this._stack.length - 1] ?? Context.ROOT_CONTEXT;
return this._stack[this._stack.length - 1] ?? ROOT_CONTEXT;
}

with<T extends (...args: unknown[]) => ReturnType<T>>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { Context } from '@opentelemetry/context-base';
import { Context, ROOT_CONTEXT } from '@opentelemetry/context-base';
import { AsyncLocalStorage } from 'async_hooks';
import { AbstractAsyncHooksContextManager } from './AbstractAsyncHooksContextManager';

Expand All @@ -27,7 +27,7 @@ export class AsyncLocalStorageContextManager extends AbstractAsyncHooksContextMa
}

active(): Context {
return this._asyncLocalStorage.getStore() ?? Context.ROOT_CONTEXT;
return this._asyncLocalStorage.getStore() ?? ROOT_CONTEXT;
}

with<T extends (...args: unknown[]) => ReturnType<T>>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
AsyncLocalStorageContextManager,
} from '../src';
import { EventEmitter } from 'events';
import { Context } from '@opentelemetry/context-base';
import { createContextKey, ROOT_CONTEXT } from '@opentelemetry/context-base';

for (const contextManagerClass of [
AsyncHooksContextManager,
Expand All @@ -30,7 +30,7 @@ for (const contextManagerClass of [
let contextManager:
| AsyncHooksContextManager
| AsyncLocalStorageContextManager;
const key1 = Context.createKey('test key 1');
const key1 = createContextKey('test key 1');

before(function () {
if (
Expand Down Expand Up @@ -77,11 +77,11 @@ for (const contextManagerClass of [

describe('.with()', () => {
it('should run the callback (null as target)', done => {
contextManager.with(Context.ROOT_CONTEXT, done);
contextManager.with(ROOT_CONTEXT, done);
});

it('should run the callback (object as target)', done => {
const test = Context.ROOT_CONTEXT.setValue(key1, 1);
const test = ROOT_CONTEXT.setValue(key1, 1);
contextManager.with(test, () => {
assert.strictEqual(
contextManager.active(),
Expand All @@ -94,24 +94,24 @@ for (const contextManagerClass of [

it('should run the callback (when disabled)', done => {
contextManager.disable();
contextManager.with(Context.ROOT_CONTEXT, () => {
contextManager.with(ROOT_CONTEXT, () => {
contextManager.enable();
return done();
});
});

it('should rethrow errors', done => {
assert.throws(() => {
contextManager.with(Context.ROOT_CONTEXT, () => {
contextManager.with(ROOT_CONTEXT, () => {
throw new Error('This should be rethrown');
});
});
return done();
});

it('should finally restore an old context', done => {
const ctx1 = Context.ROOT_CONTEXT.setValue(key1, 'ctx1');
const ctx2 = Context.ROOT_CONTEXT.setValue(key1, 'ctx2');
const ctx1 = ROOT_CONTEXT.setValue(key1, 'ctx1');
const ctx2 = ROOT_CONTEXT.setValue(key1, 'ctx2');
contextManager.with(ctx1, () => {
assert.strictEqual(contextManager.active(), ctx1);
contextManager.with(ctx2, () => {
Expand All @@ -123,7 +123,7 @@ for (const contextManagerClass of [
});

it('should finally restore an old context', done => {
const ctx1 = Context.ROOT_CONTEXT.setValue(key1, 'ctx1');
const ctx1 = ROOT_CONTEXT.setValue(key1, 'ctx1');
contextManager.with(ctx1, () => {
assert.strictEqual(contextManager.active(), ctx1);
setTimeout(() => {
Expand All @@ -150,7 +150,7 @@ for (const contextManagerClass of [
);
assert.strictEqual(contextManager.active(), scope1);
});
assert.strictEqual(contextManager.active(), Context.ROOT_CONTEXT);
assert.strictEqual(contextManager.active(), ROOT_CONTEXT);
});

it('should not loose the context', done => {
Expand All @@ -162,7 +162,7 @@ for (const contextManagerClass of [
assert.strictEqual(contextManager.active(), scope1);
return done();
});
assert.strictEqual(contextManager.active(), Context.ROOT_CONTEXT);
assert.strictEqual(contextManager.active(), ROOT_CONTEXT);
});

it('should correctly restore context using async/await', async () => {
Expand All @@ -186,7 +186,7 @@ for (const contextManagerClass of [
});
assert.strictEqual(contextManager.active(), scope1);
});
assert.strictEqual(contextManager.active(), Context.ROOT_CONTEXT);
assert.strictEqual(contextManager.active(), ROOT_CONTEXT);
});

it('should works with multiple concurrent operations', done => {
Expand All @@ -208,7 +208,7 @@ for (const contextManagerClass of [
}, 100);
assert.strictEqual(contextManager.active(), scope1);
});
assert.strictEqual(contextManager.active(), Context.ROOT_CONTEXT);
assert.strictEqual(contextManager.active(), ROOT_CONTEXT);
contextManager.with(scope2, async () => {
assert.strictEqual(contextManager.active(), scope2);
setTimeout(() => {
Expand All @@ -220,7 +220,7 @@ for (const contextManagerClass of [
}, 20);
assert.strictEqual(contextManager.active(), scope2);
});
assert.strictEqual(contextManager.active(), Context.ROOT_CONTEXT);
assert.strictEqual(contextManager.active(), ROOT_CONTEXT);
});

it('should work with timers using the same timeout', done => {
Expand Down Expand Up @@ -255,24 +255,18 @@ for (const contextManagerClass of [
describe('.bind(function)', () => {
it('should return the same target (when enabled)', () => {
const test = { a: 1 };
assert.deepStrictEqual(
contextManager.bind(test, Context.ROOT_CONTEXT),
test
);
assert.deepStrictEqual(contextManager.bind(test, ROOT_CONTEXT), test);
});

it('should return the same target (when disabled)', () => {
contextManager.disable();
const test = { a: 1 };
assert.deepStrictEqual(
contextManager.bind(test, Context.ROOT_CONTEXT),
test
);
assert.deepStrictEqual(contextManager.bind(test, ROOT_CONTEXT), test);
contextManager.enable();
});

it('should return current context (when enabled)', done => {
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const fn = contextManager.bind(() => {
assert.strictEqual(
contextManager.active(),
Expand All @@ -290,7 +284,7 @@ for (const contextManagerClass of [
*/
it('should return current context (when disabled)', done => {
contextManager.disable();
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const fn = contextManager.bind(() => {
assert.strictEqual(
contextManager.active(),
Expand All @@ -303,7 +297,7 @@ for (const contextManagerClass of [
});

it('should fail to return current context with async op', done => {
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const fn = contextManager.bind(() => {
assert.strictEqual(contextManager.active(), context);
setTimeout(() => {
Expand All @@ -322,24 +316,18 @@ for (const contextManagerClass of [
describe('.bind(event-emitter)', () => {
it('should return the same target (when enabled)', () => {
const ee = new EventEmitter();
assert.deepStrictEqual(
contextManager.bind(ee, Context.ROOT_CONTEXT),
ee
);
assert.deepStrictEqual(contextManager.bind(ee, ROOT_CONTEXT), ee);
});

it('should return the same target (when disabled)', () => {
const ee = new EventEmitter();
contextManager.disable();
assert.deepStrictEqual(
contextManager.bind(ee, Context.ROOT_CONTEXT),
ee
);
assert.deepStrictEqual(contextManager.bind(ee, ROOT_CONTEXT), ee);
});

it('should return current context and removeListener (when enabled)', done => {
const ee = new EventEmitter();
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const patchedEe = contextManager.bind(ee, context);
const handler = () => {
assert.deepStrictEqual(contextManager.active(), context);
Expand All @@ -354,7 +342,7 @@ for (const contextManagerClass of [

it('should return current context and removeAllListener (when enabled)', done => {
const ee = new EventEmitter();
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const patchedEe = contextManager.bind(ee, context);
const handler = () => {
assert.deepStrictEqual(contextManager.active(), context);
Expand All @@ -374,7 +362,7 @@ for (const contextManagerClass of [
it('should return context (when disabled)', done => {
contextManager.disable();
const ee = new EventEmitter();
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const patchedEe = contextManager.bind(ee, context);
const handler = () => {
assert.deepStrictEqual(contextManager.active(), context);
Expand All @@ -389,7 +377,7 @@ for (const contextManagerClass of [

it('should not return current context with async op', done => {
const ee = new EventEmitter();
const context = Context.ROOT_CONTEXT.setValue(key1, 1);
const context = ROOT_CONTEXT.setValue(key1, 1);
const patchedEe = contextManager.bind(ee, context);
const handler = () => {
assert.deepStrictEqual(contextManager.active(), context);
Expand Down
10 changes: 5 additions & 5 deletions packages/opentelemetry-context-base/src/NoopContextManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@
* limitations under the License.
*/

import { ROOT_CONTEXT } from './context';
import * as types from './types';
import { Context } from './context';

export class NoopContextManager implements types.ContextManager {
active(): Context {
return Context.ROOT_CONTEXT;
active(): types.Context {
return ROOT_CONTEXT;
}

with<T extends (...args: unknown[]) => ReturnType<T>>(
context: Context,
context: types.Context,
fn: T
): ReturnType<T> {
return fn();
}

bind<T>(target: T, context?: Context): T {
bind<T>(target: T, context?: types.Context): T {
return target;
}

Expand Down
33 changes: 14 additions & 19 deletions packages/opentelemetry-context-base/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class Context {
private _currentContext: Map<symbol, unknown>;

/** The root context is used as the default parent context when there is no active context */
public static readonly ROOT_CONTEXT = new Context();

/**
* This is another identifier to the root context which allows developers to easily search the
* codebase for direct uses of context which need to be removed in later PRs.
*
* It's existence is temporary and it should be removed when all references are fixed.
*/
public static readonly TODO = Context.ROOT_CONTEXT;
import { Context } from './types';

/** Get a key to uniquely identify a context value */
public static createKey(description: string) {
return Symbol.for(description);
}
export class BaseContext implements Context {
private _currentContext: Map<symbol, unknown>;

/**
* Construct a new context which inherits values from an optional parent context.
*
* @param parentContext a context from which to inherit values
*/
private constructor(parentContext?: Map<symbol, unknown>) {
constructor(parentContext?: Map<symbol, unknown>) {
this._currentContext = parentContext ? new Map(parentContext) : new Map();
}

Expand All @@ -58,7 +45,7 @@ export class Context {
* @param value value to set for the given key
*/
setValue(key: symbol, value: unknown): Context {
const context = new Context(this._currentContext);
const context = new BaseContext(this._currentContext);
context._currentContext.set(key, value);
return context;
}
Expand All @@ -70,8 +57,16 @@ export class Context {
* @param key context key for which to clear a value
*/
deleteValue(key: symbol): Context {
const context = new Context(this._currentContext);
const context = new BaseContext(this._currentContext);
context._currentContext.delete(key);
return context;
}
}

/** The root context is used as the default parent context when there is no active context */
export const ROOT_CONTEXT: Context = new BaseContext();

/** Get a key to uniquely identify a context value */
export function createContextKey(description: string) {
return Symbol.for(description);
}
4 changes: 2 additions & 2 deletions packages/opentelemetry-context-base/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

export * from './types';
export * from './context';
export { createContextKey, ROOT_CONTEXT } from './context';
export * from './NoopContextManager';
export * from './types';
Loading

0 comments on commit 75ae34c

Please sign in to comment.