Skip to content

Commit 3f5b4ba

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

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ export function invokeOrchestrionInstrumentation<Callback extends Instrumentatio
5858
return;
5959
}
6060

61-
const run = (): void => {
61+
// cleanup function is passed in so that we only remove the listener
62+
// once the callback is actually instrumented and called.
63+
const run = (cleanup?: () => void): void => {
6264
// Mark as instrumented only if the channel binding actually lands.
6365
// Avoids a very narrow case where the binding never arrives within the
6466
// retry window. So, don't mark until we know we're actually calling.
@@ -67,6 +69,7 @@ export function invokeOrchestrionInstrumentation<Callback extends Instrumentatio
6769
return;
6870
}
6971
markInstrumented(callback);
72+
cleanup?.();
7073
callback(...args);
7174
});
7275
};
@@ -88,8 +91,7 @@ export function invokeOrchestrionInstrumentation<Callback extends Instrumentatio
8891
return;
8992
}
9093
if (moduleNames.includes(moduleName)) {
91-
run();
92-
cleanup();
94+
run(cleanup);
9395
}
9496
});
9597
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,29 @@ describe('invokeOrchestrionInstrumentation', () => {
100100
expect(callback).toHaveBeenCalledTimes(1);
101101
});
102102

103+
it('keeps the listener when the binding is not ready, so a later injection recovers', async () => {
104+
// No async-context strategy, so the first injection finds no binding.
105+
setAsyncContextStrategy(undefined);
106+
const client = makeClient();
107+
const callback = vi.fn();
108+
109+
invokeOrchestrionInstrumentation(client as never, ['pg', 'pg-pool'], callback, []);
110+
expect(client.listenerCount()).toBe(1);
111+
112+
// First matching injection fires with no binding: the single retry bails,
113+
// the callback stays unmarked, and the listener must remain for a retry.
114+
client.inject('pg');
115+
await new Promise(resolve => setTimeout(resolve, 10));
116+
expect(callback).not.toHaveBeenCalled();
117+
expect(client.listenerCount()).toBe(1);
118+
119+
// Binding now available; a later matching injection subscribes.
120+
installBinding();
121+
client.inject('pg-pool');
122+
expect(callback).toHaveBeenCalledTimes(1);
123+
expect(client.listenerCount()).toBe(0);
124+
});
125+
103126
it('matches on any of several module names', () => {
104127
const client = makeClient();
105128
const callback = vi.fn();

0 commit comments

Comments
 (0)