Skip to content

Commit 14c77f8

Browse files
Flarnadyladan
andcommitted
feat: add support to forward args in context.with (open-telemetry#1883)
Co-authored-by: Daniel Dyla <[email protected]>
1 parent 98364e8 commit 14c77f8

File tree

5 files changed

+65
-11
lines changed

5 files changed

+65
-11
lines changed

api/src/api/context.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,16 @@ export class ContextAPI {
7878
*
7979
* @param context context to be active during function execution
8080
* @param fn function to execute in a context
81+
* @param thisArg optional receiver to be used for calling fn
82+
* @param args optional arguments forwarded to fn
8183
*/
82-
public with<T extends (...args: unknown[]) => ReturnType<T>>(
84+
public with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(
8385
context: Context,
84-
fn: T
85-
): ReturnType<T> {
86-
return this._getContextManager().with(context, fn);
86+
fn: F,
87+
thisArg?: ThisParameterType<F>,
88+
...args: A
89+
): ReturnType<F> {
90+
return this._getContextManager().with(context, fn, thisArg, ...args);
8791
}
8892

8993
/**

api/src/context-base/NoopContextManager.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ export class NoopContextManager implements types.ContextManager {
2222
return ROOT_CONTEXT;
2323
}
2424

25-
with<T extends (...args: unknown[]) => ReturnType<T>>(
25+
with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(
2626
_context: types.Context,
27-
fn: T
28-
): ReturnType<T> {
29-
return fn();
27+
fn: F,
28+
thisArg?: ThisParameterType<F>,
29+
...args: A
30+
): ReturnType<F> {
31+
return fn.call(thisArg, ...args);
3032
}
3133

3234
bind<T>(target: T, _context?: types.Context): T {

api/src/context-base/types.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ export interface ContextManager {
5050
* Run the fn callback with object set as the current active context
5151
* @param context Any object to set as the current active context
5252
* @param fn A callback to be immediately run within a specific context
53+
* @param thisArg optional receiver to be used for calling fn
54+
* @param args optional arguments forwarded to fn
5355
*/
54-
with<T extends (...args: unknown[]) => ReturnType<T>>(
56+
with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(
5557
context: Context,
56-
fn: T
57-
): ReturnType<T>;
58+
fn: F,
59+
thisArg?: ThisParameterType<F>,
60+
...args: A
61+
): ReturnType<F>;
5862

5963
/**
6064
* Bind an object as the current context (or a specific one)

api/test/api/api.test.ts

+20
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,26 @@ describe('API', () => {
4141
assert.strictEqual(typeof tracer, 'object');
4242
});
4343

44+
describe('Context', () => {
45+
it('with should forward this, arguments and return value', () => {
46+
function fnWithThis(this: string, a: string, b: number): string {
47+
assert.strictEqual(this, 'that');
48+
assert.strictEqual(arguments.length, 2);
49+
assert.strictEqual(a, 'one');
50+
assert.strictEqual(b, 2);
51+
return 'done';
52+
}
53+
54+
const res = context.with(ROOT_CONTEXT, fnWithThis, 'that', 'one', 2);
55+
assert.strictEqual(res, 'done');
56+
57+
assert.strictEqual(
58+
context.with(ROOT_CONTEXT, () => 3.14),
59+
3.14
60+
);
61+
});
62+
});
63+
4464
describe('GlobalTracerProvider', () => {
4565
const spanContext = {
4666
traceId: 'd4cda95b652f4a1592b449d5929fda1b',

api/test/context-base/NoopContextManager.test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,30 @@ describe('NoopContextManager', () => {
7070
return done();
7171
});
7272
});
73+
74+
it('should forward this, arguments and return value', () => {
75+
function fnWithThis(this: string, a: string, b: number): string {
76+
assert.strictEqual(this, 'that');
77+
assert.strictEqual(arguments.length, 2);
78+
assert.strictEqual(a, 'one');
79+
assert.strictEqual(b, 2);
80+
return 'done';
81+
}
82+
83+
const res = contextManager.with(
84+
ROOT_CONTEXT,
85+
fnWithThis,
86+
'that',
87+
'one',
88+
2
89+
);
90+
assert.strictEqual(res, 'done');
91+
92+
assert.strictEqual(
93+
contextManager.with(ROOT_CONTEXT, () => 3.14),
94+
3.14
95+
);
96+
});
7397
});
7498

7599
describe('.active()', () => {

0 commit comments

Comments
 (0)