Skip to content

Commit be3fd85

Browse files
refactor(wrangler): share pending metrics requests across all dispatchers
Move the requests tracking from per-dispatcher instance to module-level scope so that all dispatchers share the same Set of pending requests. This ensures all metrics requests are awaited before Wrangler exits, regardless of which dispatcher created them. - Add module-level pendingRequests Set with auto-cleanup via .finally() - Export waitForAllMetricsDispatches() to await all pending requests - Remove the per-dispatcher requests getter
1 parent 9367e7c commit be3fd85

File tree

4 files changed

+33
-37
lines changed

4 files changed

+33
-37
lines changed

packages/wrangler/src/__tests__/metrics.test.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ import {
1818
readMetricsConfig,
1919
writeMetricsConfig,
2020
} from "../metrics/metrics-config";
21-
import { getMetricsDispatcher } from "../metrics/metrics-dispatcher";
21+
import {
22+
getMetricsDispatcher,
23+
waitForAllMetricsDispatches,
24+
} from "../metrics/metrics-dispatcher";
2225
import { sniffUserAgent } from "../package-manager";
2326
import { mockConsoleMethods } from "./helpers/mock-console";
2427
import { useMockIsTTY } from "./helpers/mock-istty";
@@ -79,7 +82,8 @@ describe("metrics", () => {
7982
});
8083
});
8184

82-
afterEach(() => {
85+
afterEach(async () => {
86+
await waitForAllMetricsDispatches();
8387
vi.useRealTimers();
8488
});
8589

@@ -101,7 +105,7 @@ describe("metrics", () => {
101105
sendMetrics: true,
102106
});
103107
dispatcher.sendAdhocEvent("some-event", { a: 1, b: 2 });
104-
await Promise.all(dispatcher.requests);
108+
await waitForAllMetricsDispatches();
105109
expect(requests.count).toBe(1);
106110
expect(std.debug).toMatchInlineSnapshot(
107111
`"Metrics dispatcher: Posting data {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"agent\\":null,\\"a\\":1,\\"b\\":2}}"`
@@ -118,7 +122,7 @@ describe("metrics", () => {
118122
sendMetrics: true,
119123
});
120124
dispatcher.sendAdhocEvent("version-test");
121-
await Promise.all(dispatcher.requests);
125+
await waitForAllMetricsDispatches();
122126
expect(requests.count).toBe(1);
123127
expect(std.debug).toContain('"wranglerVersion":"1.2.3"');
124128
expect(std.debug).toContain('"wranglerMajorVersion":1');
@@ -152,7 +156,7 @@ describe("metrics", () => {
152156
sendMetrics: true,
153157
});
154158
dispatcher.sendAdhocEvent("some-event", { a: 1, b: 2 });
155-
await Promise.all(dispatcher.requests);
159+
await waitForAllMetricsDispatches();
156160

157161
expect(std.debug).toMatchInlineSnapshot(`
158162
"Metrics dispatcher: Posting data {\\"deviceId\\":\\"f82b1f46-eb7b-4154-aa9f-ce95f23b2288\\",\\"event\\":\\"some-event\\",\\"timestamp\\":1733961600000,\\"properties\\":{\\"category\\":\\"Workers\\",\\"wranglerVersion\\":\\"1.2.3\\",\\"wranglerMajorVersion\\":1,\\"wranglerMinorVersion\\":2,\\"wranglerPatchVersion\\":3,\\"os\\":\\"foo:bar\\",\\"agent\\":null,\\"a\\":1,\\"b\\":2}}
@@ -194,7 +198,7 @@ describe("metrics", () => {
194198
sendMetrics: true,
195199
});
196200
dispatcher.sendAdhocEvent("some-event", { a: 1 });
197-
await Promise.all(dispatcher.requests);
201+
await waitForAllMetricsDispatches();
198202

199203
expect(requests.count).toBe(1);
200204
expect(std.debug).toContain('"agent":"claude-code"');
@@ -210,34 +214,13 @@ describe("metrics", () => {
210214
sendMetrics: true,
211215
});
212216
dispatcher.sendAdhocEvent("some-event", { a: 1 });
213-
await Promise.all(dispatcher.requests);
217+
await waitForAllMetricsDispatches();
214218

215219
expect(requests.count).toBe(1);
216220
expect(std.debug).toContain('"agent":null');
217221
});
218222
});
219223

220-
it("should keep track of all requests made", async () => {
221-
const requests = mockMetricRequest();
222-
const dispatcher = getMetricsDispatcher({
223-
sendMetrics: true,
224-
});
225-
226-
dispatcher.sendAdhocEvent("some-event", { a: 1, b: 2 });
227-
expect(dispatcher.requests.length).toBe(1);
228-
229-
expect(requests.count).toBe(0);
230-
await Promise.allSettled(dispatcher.requests);
231-
expect(requests.count).toBe(1);
232-
233-
dispatcher.sendAdhocEvent("another-event", { c: 3, d: 4 });
234-
expect(dispatcher.requests.length).toBe(2);
235-
236-
expect(requests.count).toBe(1);
237-
await Promise.allSettled(dispatcher.requests);
238-
expect(requests.count).toBe(2);
239-
});
240-
241224
describe("sendCommandEvent()", () => {
242225
const reused = {
243226
wranglerVersion: "1.2.3",

packages/wrangler/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ import {
9191
kvNamespaceRenameCommand,
9292
} from "./kv";
9393
import { logger, LOGGER_LEVELS } from "./logger";
94-
import { getMetricsDispatcher } from "./metrics";
94+
import { getMetricsDispatcher, waitForAllMetricsDispatches } from "./metrics";
9595
import {
9696
metricsAlias,
9797
telemetryDisableCommand,
@@ -1866,7 +1866,7 @@ export async function main(argv: string[]): Promise<void> {
18661866

18671867
// Wait for any pending telemetry requests to complete (with timeout)
18681868
await Promise.race([
1869-
Promise.allSettled(dispatcher?.requests ?? []),
1869+
waitForAllMetricsDispatches(),
18701870
setTimeout(1000, undefined, { ref: false }),
18711871
]);
18721872
} catch (e) {
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
export { getMetricsDispatcher } from "./metrics-dispatcher";
1+
export {
2+
getMetricsDispatcher,
3+
waitForAllMetricsDispatches,
4+
} from "./metrics-dispatcher";
25
export { getMetricsConfig } from "./metrics-config";
36
export * from "./send-event";
47
export { getMetricsUsageHeaders } from "./metrics-usage-headers";

packages/wrangler/src/metrics/metrics-dispatcher.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ import type { CommonEventProperties, Events } from "./types";
3030

3131
const SPARROW_URL = "https://sparrow.cloudflare.com";
3232

33+
// Module-level Set to track all pending requests across all dispatchers.
34+
// Promises are automatically removed from this Set once they settle.
35+
const pendingRequests = new Set<Promise<void>>();
36+
37+
/**
38+
* Wait for all pending metrics requests to complete.
39+
* This should be called before the process exits to ensure all metrics are sent.
40+
*/
41+
export function waitForAllMetricsDispatches(): Promise<void> {
42+
return Promise.allSettled(pendingRequests).then(() => {});
43+
}
44+
3345
/**
3446
* A list of all the command args that can be included in the event.
3547
*
@@ -58,7 +70,6 @@ export function getMetricsDispatcher(options: MetricsConfigOptions) {
5870
// The SPARROW_SOURCE_KEY will be provided at build time through esbuild's `define` option
5971
// No events will be sent if the env `SPARROW_SOURCE_KEY` is not provided and the value will be set to an empty string instead.
6072
const SPARROW_SOURCE_KEY = process.env.SPARROW_SOURCE_KEY ?? "";
61-
const requests: Array<Promise<void>> = [];
6273
const wranglerVersion = getWranglerVersion();
6374
const [wranglerMajorVersion, wranglerMinorVersion, wranglerPatchVersion] =
6475
wranglerVersion.split(".").map((v) => parseInt(v, 10));
@@ -181,10 +192,6 @@ export function getMetricsDispatcher(options: MetricsConfigOptions) {
181192
logger.debug("Error sending metrics event", err);
182193
}
183194
},
184-
185-
get requests() {
186-
return requests;
187-
},
188195
};
189196

190197
function dispatch(event: { name: string; properties: Properties }) {
@@ -241,9 +248,12 @@ export function getMetricsDispatcher(options: MetricsConfigOptions) {
241248
"Metrics dispatcher: Failed to send request:",
242249
(e as Error).message
243250
);
251+
})
252+
.finally(() => {
253+
pendingRequests.delete(request);
244254
});
245255

246-
requests.push(request);
256+
pendingRequests.add(request);
247257
}
248258

249259
function printMetricsBanner() {

0 commit comments

Comments
 (0)