Skip to content

Commit 5a4d562

Browse files
committed
fix(webapp): guard prom metrics registration against vite dev HMR re-evaluation
1 parent d76468d commit 5a4d562

1 file changed

Lines changed: 27 additions & 22 deletions

File tree

apps/webapp/app/utils/reloadingRegistry.server.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,34 @@ import { Counter, Gauge } from "prom-client";
33
import { metricsRegister } from "~/metrics.server";
44
import { logger } from "~/services/logger.server";
55
import { signalsEmitter } from "~/services/signals.server";
6+
import { singleton } from "~/utils/singleton";
67

7-
const loadFailures = new Counter({
8-
name: "reloading_registry_load_failures_total",
9-
help: "Failed loads of a reloading registry",
10-
labelNames: ["name"],
11-
registers: [metricsRegister],
12-
});
13-
14-
const lastSuccessfulLoadAt = new Gauge({
15-
name: "reloading_registry_last_successful_load_timestamp_seconds",
16-
help: "Unix time of the last successful registry load (staleness signal)",
17-
labelNames: ["name"],
18-
registers: [metricsRegister],
19-
});
20-
21-
// 0 until the first successful load, then 1. Starts at 0 (not absent) so a
22-
// never-loaded registry is an alertable series, distinct from "feature off".
23-
const registryLoaded = new Gauge({
24-
name: "reloading_registry_loaded",
25-
help: "1 once the registry has loaded at least once, else 0 (0 = serving cold fallback)",
26-
labelNames: ["name"],
27-
registers: [metricsRegister],
28-
});
8+
// singleton: module-scope registrations double-register under Vite dev HMR
9+
const { loadFailures, lastSuccessfulLoadAt, registryLoaded } = singleton(
10+
"reloadingRegistryMetrics",
11+
() => ({
12+
loadFailures: new Counter({
13+
name: "reloading_registry_load_failures_total",
14+
help: "Failed loads of a reloading registry",
15+
labelNames: ["name"],
16+
registers: [metricsRegister],
17+
}),
18+
lastSuccessfulLoadAt: new Gauge({
19+
name: "reloading_registry_last_successful_load_timestamp_seconds",
20+
help: "Unix time of the last successful registry load (staleness signal)",
21+
labelNames: ["name"],
22+
registers: [metricsRegister],
23+
}),
24+
// 0 until the first successful load, then 1. Starts at 0 (not absent) so a
25+
// never-loaded registry is an alertable series, distinct from "feature off".
26+
registryLoaded: new Gauge({
27+
name: "reloading_registry_loaded",
28+
help: "1 once the registry has loaded at least once, else 0 (0 = serving cold fallback)",
29+
labelNames: ["name"],
30+
registers: [metricsRegister],
31+
}),
32+
})
33+
);
2934

3035
export type ReloadingRegistry<T> = {
3136
isReady: Promise<void>;

0 commit comments

Comments
 (0)