mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-14 19:22:32 +03:00
fix(db): wire telemetry cleanup scheduler in Next.js startup path (#9624)
This commit is contained in:
1
changelog.d/fixes/9624-telemetry-cleanup-wiring.md
Normal file
1
changelog.d/fixes/9624-telemetry-cleanup-wiring.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(db): wire telemetry cleanup scheduler in Next.js startup path (#9624)
|
||||
@@ -306,6 +306,7 @@ export async function registerNodejs(): Promise<void> {
|
||||
{ applyRuntimeSettings },
|
||||
{ startRuntimeConfigHotReload },
|
||||
{ startSpendBatchWriter },
|
||||
{ startCleanupScheduler },
|
||||
{ registerDefaultGuardrails },
|
||||
{ ensurePersistentManagementPasswordHash },
|
||||
{ skillExecutor },
|
||||
@@ -320,6 +321,7 @@ export async function registerNodejs(): Promise<void> {
|
||||
import("@/lib/config/runtimeSettings"),
|
||||
import("@/lib/config/hotReload"),
|
||||
import("@/lib/spend/batchWriter"),
|
||||
import("@/lib/db/cleanup"),
|
||||
import("@/lib/guardrails"),
|
||||
import("@/lib/auth/managementPassword"),
|
||||
import("@/lib/skills/executor"),
|
||||
@@ -489,6 +491,17 @@ export async function registerNodejs(): Promise<void> {
|
||||
console.warn("[STARTUP] Could not initialize vacuum scheduler (non-fatal):", msg);
|
||||
}
|
||||
|
||||
// Retention cleanup scheduler (#4691/#6988, #9624): runs the general retention
|
||||
// cleanup once after startup and then every 6 hours. Previously this was only
|
||||
// wired into the unused src/server-init.ts, so telemetry tables grew unboundedly
|
||||
// even with retention.autoCleanupEnabled=true. Idempotent (guarded internally).
|
||||
try {
|
||||
startCleanupScheduler();
|
||||
} catch (err: unknown) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
console.warn("[STARTUP] Could not start cleanup scheduler (non-fatal):", msg);
|
||||
}
|
||||
|
||||
// Warm the model catalog's durable, apiKey-independent sub-caches at
|
||||
// startup — see warmModelCatalogCache() for why the top-level Response
|
||||
// cache alone doesn't deliver this. Fire-and-forget, non-fatal.
|
||||
|
||||
52
tests/unit/repro-9624.test.ts
Normal file
52
tests/unit/repro-9624.test.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { describe, it } from "node:test";
|
||||
import { strict as assert } from "node:assert";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const INSTRUMENTATION_NODE_PATH = resolve(
|
||||
__dirname,
|
||||
"../../src/instrumentation-node.ts"
|
||||
);
|
||||
|
||||
describe("repro-9624: startCleanupScheduler wired in Next.js startup path", () => {
|
||||
it("should import startCleanupScheduler from cleanup", () => {
|
||||
const source = readFileSync(INSTRUMENTATION_NODE_PATH, "utf-8");
|
||||
|
||||
// instrumentation-node.ts loads all startup modules via dynamic imports in a
|
||||
// Promise.all destructure, e.g.:
|
||||
// const [{ startCleanupScheduler }, ...] = await Promise.all([
|
||||
// import("@/lib/db/cleanup"), ...
|
||||
// ]);
|
||||
// So the binding and the module import appear separately in the file.
|
||||
const cleanupModuleImported = /import\(\s*["']@\/lib\/db\/cleanup["']\s*\)/.test(
|
||||
source
|
||||
);
|
||||
const schedulerBound = /\bstartCleanupScheduler\b/.test(source);
|
||||
|
||||
assert.ok(
|
||||
cleanupModuleImported,
|
||||
"@/lib/db/cleanup should be imported (dynamic import) in instrumentation-node.ts"
|
||||
);
|
||||
assert.ok(
|
||||
schedulerBound,
|
||||
"startCleanupScheduler should be bound in instrumentation-node.ts"
|
||||
);
|
||||
});
|
||||
|
||||
it("should call startCleanupScheduler() during startup", () => {
|
||||
const source = readFileSync(INSTRUMENTATION_NODE_PATH, "utf-8");
|
||||
|
||||
// Check that startCleanupScheduler is called (as a function call).
|
||||
// It can be called directly or as part of a conditional.
|
||||
const hasCall = /\bstartCleanupScheduler\s*\(/.test(source);
|
||||
|
||||
assert.ok(
|
||||
hasCall,
|
||||
"startCleanupScheduler() should be called in instrumentation-node.ts"
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user