diff --git a/packages/opentelemetry-api/test/api/global.test.ts b/packages/opentelemetry-api/test/api/global.test.ts index 8a9a67f752d..72df9c7ab02 100644 --- a/packages/opentelemetry-api/test/api/global.test.ts +++ b/packages/opentelemetry-api/test/api/global.test.ts @@ -34,8 +34,8 @@ describe('Global Utils', () => { assert.notEqual(api1, api2); // that return separate noop instances to start assert.notStrictEqual( - api1.context['getContextManager'](), - api2.context['getContextManager']() + api1.context.getContextManager(), + api2.context.getContextManager() ); beforeEach(() => { @@ -46,33 +46,33 @@ describe('Global Utils', () => { }); it('should change the global context manager', () => { - const original = api1.context['getContextManager'](); + const original = api1.context.getContextManager(); const newContextManager = new NoopContextManager(); api1.context.setGlobalContextManager(newContextManager); - assert.notStrictEqual(api1.context['getContextManager'](), original); - assert.strictEqual(api1.context['getContextManager'](), newContextManager); + assert.notStrictEqual(api1.context.getContextManager(), original); + assert.strictEqual(api1.context.getContextManager(), newContextManager); }); it('should load an instance from one which was set in the other', () => { api1.context.setGlobalContextManager(new NoopContextManager()); assert.strictEqual( - api1.context['getContextManager'](), - api2.context['getContextManager']() + api1.context.getContextManager(), + api2.context.getContextManager() ); }); it('should disable both if one is disabled', () => { - const original = api1.context['getContextManager'](); + const original = api1.context.getContextManager(); api1.context.setGlobalContextManager(new NoopContextManager()); - assert.notStrictEqual(original, api1.context['getContextManager']()); + assert.notStrictEqual(original, api1.context.getContextManager()); api2.context.disable(); - assert.strictEqual(original, api1.context['getContextManager']()); + assert.strictEqual(original, api1.context.getContextManager()); }); it('should return the module NoOp implementation if the version is a mismatch', () => { - const original = api1.context['getContextManager'](); + const original = api1.context.getContextManager(); api1.context.setGlobalContextManager(new NoopContextManager()); const afterSet = _global[GLOBAL_CONTEXT_MANAGER_API_KEY]!(-1); diff --git a/packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts b/packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts index 4ea8fe78d4a..6925967f1db 100644 --- a/packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts +++ b/packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts @@ -67,10 +67,7 @@ export class AsyncHooksContextManager implements ContextManager { return ref === undefined ? Context.ROOT_CONTEXT : ref.get(); } - with ReturnType>( - context: Context, - fn: T - ): ReturnType { + with ReturnType>(context: Context, fn: T): ReturnType { const uid = asyncHooks.executionAsyncId(); let ref = this._contextRefs.get(uid); let oldContext: Context | undefined = undefined; @@ -94,10 +91,10 @@ export class AsyncHooksContextManager implements ContextManager { } } - async withAsync, U extends (...args: unknown[]) => T>( + async withAsync Promise>( context: Context, fn: U - ): Promise { + ): Promise { const uid = asyncHooks.executionAsyncId(); let ref = this._contextRefs.get(uid); let oldContext: Context | undefined = undefined; @@ -109,7 +106,7 @@ export class AsyncHooksContextManager implements ContextManager { ref.set(context); } try { - return await fn(); + await fn(); } catch (err) { throw err; } finally { diff --git a/packages/opentelemetry-node/src/NodeTracer.ts b/packages/opentelemetry-node/src/NodeTracer.ts index c838e306860..830c11fb933 100644 --- a/packages/opentelemetry-node/src/NodeTracer.ts +++ b/packages/opentelemetry-node/src/NodeTracer.ts @@ -16,31 +16,43 @@ import * as api from '@opentelemetry/api'; import { setActiveSpan } from '@opentelemetry/core'; -import { - BasicTracerProvider, - Tracer, - TracerConfig, -} from '@opentelemetry/tracing'; +import { Tracer } from '@opentelemetry/tracing'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; +export type Parameters = T extends (...args: infer T) => any ? T : unknown[]; +// Used to get return type from patched function used for type our memoize function +// (we remove the promise, the original function should be an async function) +export type ReturnType = T extends (...args: any[]) => infer T + ? Unpromisify + : string | object; +// Used to type the patched function (with the promise) +export type OriginalReturnType = Promise>; +// Type of the original function with params and promise as result +export type Func = (...args: Parameters) => OriginalReturnType; +// Type of our memoize function with original params and promise with original returns types +// we need to remove promise from the original function and set it again to be sure to only +// have one level of promise (avoid Promise>) +export type AsyncFunc = () => Promise>; +// Used to remove promise from a type +export type Unpromisify = T extends Promise ? R : T; + /** * This class represents a nodejs-specific tracer. */ export class NodeTracer extends Tracer { /** - * Constructs a new NodeTracer instance. + * Execute the provided function with the given span in the current context. + * + * **NOTE**: This function is experimental, refer to to + * https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node#withspanasync */ - constructor(config: TracerConfig, _tracerProvider: BasicTracerProvider) { - super(config, _tracerProvider); - } - - async withSpanAsync< - T extends Promise, - U extends (...args: unknown[]) => T - >(span: api.Span, fn: U): Promise { + async withSpanAsync Promise>( + span: api.Span, + fn: U + ): Promise { const contextManager = api.context.getContextManager(); if (contextManager instanceof AsyncHooksContextManager) { - return contextManager.withAsync( + await contextManager.withAsync( setActiveSpan(api.context.active(), span), fn ); @@ -48,7 +60,7 @@ export class NodeTracer extends Tracer { this.logger.warn( `Using withAsync without AsyncHookContextManager doesn't work, please refer to https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node#withspanasync` ); - return await fn(); + await fn(); } } }