Skip to content

Commit c046592

Browse files
committed
fixup! fix(server-utils): Ensure orchestrion instrumentation lazy registers on Node (#22518)
1 parent ae93c4e commit c046592

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

packages/server-utils/src/orchestrion/instrumentation.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,14 @@ export function invokeOrchestrionInstrumentation<Callback extends Instrumentatio
5959
}
6060

6161
const run = (): void => {
62-
markInstrumented(callback);
62+
// Mark as instrumented only if the channel binding actually lands.
63+
// Avoids a very narrow case where the binding never arrives within the
64+
// retry window. So, don't mark until we know we're actually calling.
6365
waitForTracingChannelBinding(() => {
66+
if (hasBeenInstrumented(callback)) {
67+
return;
68+
}
69+
markInstrumented(callback);
6470
callback(...args);
6571
});
6672
};

packages/server-utils/test/orchestrion/instrumentation.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,26 @@ describe('invokeOrchestrionInstrumentation', () => {
5858
expect(client.listenerCount()).toBe(0);
5959
});
6060

61+
it('does not mark the callback when the binding never becomes available, so a later attempt recovers', async () => {
62+
GLOBAL_OBJ.__SENTRY_ORCHESTRION__ = { runtime: ['mysql'] };
63+
// No async-context strategy, so `waitForTracingChannelBinding` finds no binding and gives up.
64+
setAsyncContextStrategy(undefined);
65+
const client = makeClient();
66+
const callback = vi.fn();
67+
68+
invokeOrchestrionInstrumentation(client as never, ['mysql'], callback, []);
69+
70+
// Wait past `waitForTracingChannelBinding`'s single ~1ms retry; it bails without subscribing.
71+
await new Promise(resolve => setTimeout(resolve, 10));
72+
expect(callback).not.toHaveBeenCalled();
73+
74+
// The callback must NOT have been marked as instrumented — once the binding exists, a later
75+
// invocation subscribes rather than being permanently skipped.
76+
installBinding();
77+
invokeOrchestrionInstrumentation(client as never, ['mysql'], callback, []);
78+
expect(callback).toHaveBeenCalledTimes(1);
79+
});
80+
6181
it('does not subscribe until the module is injected at runtime', () => {
6282
const client = makeClient();
6383
const callback = vi.fn();

0 commit comments

Comments
 (0)