Skip to content

Commit 157ceb5

Browse files
committed
Add bindContext support
1 parent 39eb7f4 commit 157ceb5

File tree

7 files changed

+29
-5
lines changed

7 files changed

+29
-5
lines changed

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
22.12
1+
24.3.0

library/agent/hooks/instrumentation/injectedFunctions.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getInstance } from "../../AgentSingleton";
2-
import { getContext } from "../../Context";
2+
import { bindContext, getContext } from "../../Context";
33
import { inspectArgs } from "../wrapExport";
44
import { getPackageCallbackInfo } from "./instructions";
55

@@ -67,7 +67,17 @@ export function __instrumentModifyArgs(
6767
const newArgs = cbInfo.funcs.modifyArgs(args, agent, subject);
6868
// Only return the new arguments if they are an array
6969
if (Array.isArray(newArgs)) {
70-
return newArgs;
70+
if (!cbInfo.funcs.bindContext) {
71+
return newArgs;
72+
}
73+
74+
// Ensure that all functions in the new arguments are bound to the current execution context (only if bindContext is true)
75+
return newArgs.map((arg) => {
76+
if (typeof arg === "function") {
77+
return bindContext(arg as () => unknown);
78+
}
79+
return arg;
80+
});
7181
}
7282
} catch (error) {
7383
if (error instanceof Error) {

library/agent/hooks/instrumentation/instructions.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable max-lines-per-function */
12
import { Package } from "../Package";
23
import { BuiltinModule } from "../BuiltinModule";
34
import type {
@@ -45,6 +46,12 @@ export function setPackagesToInstrument(_packages: Package[]) {
4546
functions: file.functions.map((func) => {
4647
const identifier = `${pkg.getName()}.${file.path}.${func.name}.${func.nodeType}.${versionedPackage.getRange()}`;
4748

49+
// If bindContext is set to true, but no modifyArgs is defined, modifyArgs will be set to a stub function
50+
// The reason for this is that the bindContext logic needs to modify the arguments
51+
if (func.bindContext && !func.modifyArgs) {
52+
func.modifyArgs = (args) => args;
53+
}
54+
4855
packageCallbackInfo.set(identifier, {
4956
pkgName: pkg.getName(),
5057
methodName: func.name,
@@ -53,6 +60,7 @@ export function setPackagesToInstrument(_packages: Package[]) {
5360
inspectArgs: func.inspectArgs,
5461
modifyArgs: func.modifyArgs,
5562
modifyReturnValue: func.modifyReturnValue,
63+
bindContext: func.bindContext ?? false,
5664
},
5765
});
5866

library/agent/hooks/instrumentation/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export type IntereptorFunctionsObj = {
5858
inspectArgs?: InspectArgsInterceptor;
5959
modifyArgs?: ModifyArgsInterceptor;
6060
modifyReturnValue?: ModifyReturnValueInterceptor;
61+
bindContext: boolean;
6162
};
6263

6364
export type IntereptorCallbackInfoObj = {
@@ -92,6 +93,11 @@ export type PackageFunctionInstrumentationInstruction = {
9293
* In strict mode, the arguments object and the named arguments are not synced, so changing the arguments object will not change the named arguments and vice versa.
9394
*/
9495
modifyArgumentsObject?: boolean;
96+
/**
97+
* Binds the given function to the current execution context to prevent that the Zen context using the async local storage is lost.
98+
* If enabled, the bindContext function will be called for all callbacks that are passed to the function.
99+
*/
100+
bindContext?: boolean;
95101
};
96102

97103
export type PackageFileInstrumentationInstruction = {

library/sinks/MySQL.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class MySQL implements Wrapper {
6565
name: "Connection.prototype.query",
6666
nodeType: "FunctionAssignment",
6767
operationKind: "sql_op",
68+
bindContext: true,
6869
inspectArgs: (args) => this.inspectQuery(args),
6970
},
7071
],

library/sinks/Postgres.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class Postgres implements Wrapper {
6565
nodeType: "MethodDefinition",
6666
name: "query",
6767
operationKind: "sql_op",
68+
bindContext: true,
6869
inspectArgs: (args) => this.inspectQuery(args),
6970
},
7071
],

scripts/run-tap.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ if (process.argv.includes("--test-new-instrumentation")) {
3030
"**/sinks/SQLite3.test.ts",
3131
"**/sinks/Prisma.test.ts",
3232
"**/sinks/AwsSDK*",
33-
"**/sinks/Postgres.test.ts", // Bind context
34-
"**/sinks/MySQL.test.ts", // Bind context
3533
"**/sinks/MySQL2.v3.10.test.ts",
3634

3735
"**/sources/PubSub.test.ts",

0 commit comments

Comments
 (0)