mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-21 22:52:19 +03:00
chore(startup): remove server-init.ts, a module nothing imports (#10780)
Merged — validated together with a batch of related maxmad64bis PRs in one combined worktree (typecheck:core clean, complexity/cognitive-complexity/file-size/changelog gates green, focused tests passing). Thanks for the contribution!
This commit is contained in:
@@ -891,7 +891,7 @@ NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true
|
||||
# MODEL_SYNC_INTERVAL_HOURS=24
|
||||
|
||||
# Provider limits sync interval in minutes (rate limit windows, quotas).
|
||||
# Used by: src/server-init.ts — polls provider health endpoints.
|
||||
# Used by: src/lib/usage/providerLimits.ts — polls provider health endpoints.
|
||||
# Default: 70
|
||||
PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES=70
|
||||
|
||||
|
||||
1
changelog.d/maintenance/10780-server-init-dead-code.md
Normal file
1
changelog.d/maintenance/10780-server-init-dead-code.md
Normal file
@@ -0,0 +1 @@
|
||||
- chore(startup): remove `src/server-init.ts` (183 lines, never imported — the boot path is `src/instrumentation-node.ts`) and correct four `"called from server-init.ts"` comments left pointing at the dead entry point (#10780)
|
||||
@@ -89,7 +89,6 @@ src/
|
||||
├── i18n/ Locale bundles
|
||||
├── instrumentation.ts Next.js instrumentation hook
|
||||
├── instrumentation-node.ts
|
||||
├── server-init.ts Process-level bootstrap (env, DB, jobs, sync)
|
||||
└── proxy.ts Top-level proxy bootstrap helper
|
||||
```
|
||||
|
||||
|
||||
@@ -133,7 +133,6 @@ src/
|
||||
├── types/ # Shared TS type files
|
||||
├── instrumentation.ts # Next.js telemetry hook (browser + edge)
|
||||
├── instrumentation-node.ts # Node-only instrumentation
|
||||
├── server-init.ts # Server bootstrap (DB migrations, jobs, cleanup)
|
||||
└── proxy.ts # HTTP-proxy entry shim
|
||||
```
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ stale data.
|
||||
The sync runs **on by default**:
|
||||
|
||||
- It runs once at server startup and then on a periodic timer
|
||||
(`src/lib/arenaEloSync.ts`, wired from `src/server-init.ts`).
|
||||
(`src/lib/arenaEloSync.ts`, wired from `src/instrumentation-node.ts`).
|
||||
- It is **non-blocking and never fatal** — if the upstream fetch fails, OmniRoute keeps
|
||||
running and the rankings simply show the last good data (or an empty state).
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ detection above).
|
||||
| `OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS` | `false` | `open-sse/mcp-server/descriptionCompressor.ts` | Compress MCP tool descriptions before serializing the manifest. Enable values: `1`, `true`, `on`. |
|
||||
| `OMNIROUTE_MCP_DESCRIPTION_COMPRESSION` | `rtk` | `open-sse/mcp-server/descriptionCompressor.ts` | Compression algorithm/profile. Disable values: `0`, `false`, `off`. |
|
||||
| `MODEL_SYNC_INTERVAL_HOURS` | `24` | `src/shared/services/modelSyncScheduler.ts` | Model catalog sync interval in hours. |
|
||||
| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/server-init.ts` | Provider rate-limit and quota polling interval. |
|
||||
| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/lib/usage/providerLimits.ts` | Provider rate-limit and quota polling interval. |
|
||||
| `PROVIDER_LIMITS_SYNC_SPACING_MS` | `1500` | `src/lib/usage/providerLimits.ts` | Gap (ms) between consecutive OAuth quota fetches in a bulk sync; OAuth connections are fetched one at a time to avoid bursting an upstream. `0` opts out (concurrent). |
|
||||
| `OMNIROUTE_QUOTA_FETCH_MIN_INTERVAL_MS` | `250` | `open-sse/services/quotaFetchThrottle.ts` | Min interval (ms) between consecutive upstream quota fetches on the per-request preflight/monitor path; spaces concurrent network calls so many accounts on one IP don't burst the upstream. Wired into the Codex (`/wham/usage`), DeepSeek, Bailian (both fetch sites), OpenCode, and Crof quota fetchers (#6009, #6911). The generic `usage.ts::getUsageForProvider` dispatch path (github/glm/minimax/nanogpt/xai/etc.) is not yet covered — tracked separately. Cache hits unaffected. `0` disables; clamped `0..5000`. |
|
||||
| `PROVIDER_LIMITS_POST_USAGE_REFRESH_DELAY_MS` | `5000` | `src/lib/usage/providerLimits.ts` | Delay (ms) before refreshing provider limits after a real usage event, giving the upstream quota API time to register consumption. |
|
||||
|
||||
@@ -114,7 +114,7 @@ Two separate retention windows are honoured:
|
||||
| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Row-cap trim for `proxy_logs` |
|
||||
|
||||
`cleanupExpiredLogs()` runs the retention pass. It is invoked on server startup
|
||||
from `src/server-init.ts` and `src/instrumentation-node.ts`. Each run logs a
|
||||
from `src/instrumentation-node.ts`. Each run logs a
|
||||
`compliance.cleanup` audit event with the per-table delete counts. Proxy/call
|
||||
log trimming is batched (`BATCH_SIZE = 5000`) to avoid long write locks.
|
||||
|
||||
|
||||
@@ -573,16 +573,16 @@ export function cleanupReasoningCache(): number {
|
||||
|
||||
// ──────────────── Auto-start periodic cleanup ────────────────
|
||||
//
|
||||
// server-init.ts was supposed to start the cleanup job, but that module is
|
||||
// never imported anywhere (it is stranded/dead code). As a result, the
|
||||
// reasoning_cache SQLite table accumulates expired entries indefinitely.
|
||||
// server-init.ts was supposed to start the cleanup job, but that module was
|
||||
// never imported anywhere (it was stranded dead code, since removed). As a
|
||||
// result, the reasoning_cache SQLite table accumulates expired entries
|
||||
// indefinitely.
|
||||
//
|
||||
// Fix: start the periodic cleanup directly from this module so it runs
|
||||
// regardless of how the server boots. On first import we run one
|
||||
// immediate sweep, then schedule a 30-minute interval.
|
||||
//
|
||||
// See: src/lib/jobs/reasoningCacheCleanupJob.ts (the original job module,
|
||||
// which also remains valid if server-init.ts ever gets wired in).
|
||||
// See: src/lib/jobs/reasoningCacheCleanupJob.ts (the original job module).
|
||||
|
||||
const DEFAULT_CLEANUP_INTERVAL_MS = 30 * 60 * 1000; // 30 min
|
||||
|
||||
|
||||
@@ -539,7 +539,7 @@ export function getArenaEloSyncStatus(): SyncStatus {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Init (called from server-init.ts) ───────────────────
|
||||
// ─── Init (called from instrumentation-node.ts) ───────────────────
|
||||
|
||||
/**
|
||||
* Initialize Arena ELO sync if enabled via feature flag configuration.
|
||||
|
||||
@@ -332,7 +332,7 @@ function startPeriodicSync(intervalMs?: number): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot entry point — call once from server-init.ts.
|
||||
* Boot entry point — called once from instrumentation-node.ts.
|
||||
* On by default; opt out via OPENROUTER_PROVIDER_STATS_ENABLED=false.
|
||||
*/
|
||||
export function initOpenRouterProviderStatsSync(): boolean {
|
||||
|
||||
@@ -759,7 +759,7 @@ export function getSyncStatus(): SyncStatus {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Init (called from server-init.ts) ───────────────────
|
||||
// ─── Init (called from instrumentation-node.ts) ───────────────────
|
||||
|
||||
/**
|
||||
* Initialize models.dev sync if enabled.
|
||||
|
||||
@@ -515,7 +515,7 @@ export function getSyncStatus(): SyncStatus {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Init (called from server-init.ts) ───────────────────
|
||||
// ─── Init (called from instrumentation-node.ts) ───────────────────
|
||||
|
||||
/**
|
||||
* Initialize pricing sync if enabled.
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
// Server startup script
|
||||
import initializeCloudSync from "./shared/services/initializeCloudSync";
|
||||
import { enforceWebRuntimeEnv } from "./lib/env/runtimeEnv";
|
||||
import { initAuditLog, cleanupExpiredLogs, logAuditEvent } from "./lib/compliance/index";
|
||||
import { initConsoleInterceptor } from "./lib/consoleInterceptor";
|
||||
import { registerBudgetResetJob } from "./lib/jobs/budgetResetJob";
|
||||
import { registerTokenHealthCheck } from "./lib/jobs/tokenHealthCheckJob";
|
||||
import { startReasoningCacheCleanupJob } from "./lib/jobs/reasoningCacheCleanupJob";
|
||||
import { startCleanupScheduler } from "./lib/db/cleanup";
|
||||
import { getSettings } from "./lib/db/settings";
|
||||
import { applyRuntimeSettings } from "./lib/config/runtimeSettings";
|
||||
import { setSystemPromptConfig } from "@omniroute/open-sse/services/systemPrompt.ts";
|
||||
import { hydrateThinkingBudgetConfig } from "@omniroute/open-sse/services/thinkingBudget.ts";
|
||||
import { startRuntimeConfigHotReload } from "./lib/config/hotReload";
|
||||
import { startSpendBatchWriter } from "./lib/spend/batchWriter";
|
||||
import { registerDefaultGuardrails } from "./lib/guardrails";
|
||||
import { ensurePersistentManagementPasswordHash } from "./lib/auth/managementPassword";
|
||||
import { skillExecutor } from "./lib/skills/executor";
|
||||
import { registerBuiltinSkills } from "./lib/skills/builtins";
|
||||
import { createLogger } from "./shared/utils/logger";
|
||||
|
||||
const startupLog = createLogger("server-init");
|
||||
|
||||
function getErrorMessage(error: unknown) {
|
||||
return error instanceof Error ? error.message : String(error);
|
||||
}
|
||||
|
||||
async function startServer() {
|
||||
// Trigger request-log layout migration during startup, before serving requests.
|
||||
await import("./lib/usage/migrations");
|
||||
|
||||
// Console interceptor: capture all console output to log file (must be first)
|
||||
initConsoleInterceptor();
|
||||
|
||||
// FASE-01: Validate required secrets and runtime env before anything else (fail-fast)
|
||||
enforceWebRuntimeEnv();
|
||||
|
||||
// Compliance: Initialize audit_log table
|
||||
try {
|
||||
initAuditLog();
|
||||
startupLog.info("Audit log table initialized");
|
||||
} catch (err) {
|
||||
startupLog.warn({ err }, "Could not initialize audit log");
|
||||
}
|
||||
|
||||
// Compliance: One-time cleanup of expired logs
|
||||
try {
|
||||
const cleanup = await cleanupExpiredLogs();
|
||||
if (
|
||||
cleanup.deletedUsage ||
|
||||
cleanup.deletedCallLogs ||
|
||||
cleanup.deletedProxyLogs ||
|
||||
cleanup.deletedRequestDetailLogs ||
|
||||
cleanup.deletedAuditLogs ||
|
||||
cleanup.deletedMcpAuditLogs
|
||||
) {
|
||||
startupLog.info({ cleanup }, "Expired log cleanup completed");
|
||||
}
|
||||
} catch (err) {
|
||||
startupLog.warn({ err }, "Log cleanup failed");
|
||||
}
|
||||
|
||||
startupLog.info("Starting server with cloud sync");
|
||||
|
||||
try {
|
||||
let settings = await getSettings();
|
||||
const passwordState = await ensurePersistentManagementPasswordHash({
|
||||
logger: { log: (message: string) => startupLog.info(message) },
|
||||
settings,
|
||||
source: "startup",
|
||||
});
|
||||
settings = passwordState.settings;
|
||||
const runtimeChanges = await applyRuntimeSettings(settings, { force: true, source: "startup" });
|
||||
if (runtimeChanges.length > 0) {
|
||||
startupLog.info(
|
||||
{ sections: runtimeChanges.map((entry) => entry.section) },
|
||||
"Runtime settings hydrated"
|
||||
);
|
||||
}
|
||||
|
||||
// Restore the Global System Prompt into the in-memory config. It lives in the
|
||||
// `settings.systemPrompt` key but is NOT covered by applyRuntimeSettings, so without
|
||||
// this the toggle/prompt revert to defaults on every restart (#2470).
|
||||
if (settings.systemPrompt) {
|
||||
setSystemPromptConfig(settings.systemPrompt);
|
||||
startupLog.info("Global System Prompt restored from settings");
|
||||
}
|
||||
|
||||
// Restore the proxy-level Thinking-Budget config (#5312). It lives in
|
||||
// `settings.thinkingBudget` and is NOT covered by applyRuntimeSettings, so
|
||||
// without this the dashboard mode (auto/custom/adaptive) silently reverts to
|
||||
// the passthrough default on every restart.
|
||||
if (hydrateThinkingBudgetConfig(settings)) {
|
||||
startupLog.info("Thinking-Budget config restored from settings");
|
||||
}
|
||||
|
||||
// Initialize cloud sync
|
||||
startSpendBatchWriter();
|
||||
registerDefaultGuardrails();
|
||||
registerBuiltinSkills(skillExecutor);
|
||||
startupLog.info("Spend batch writer started");
|
||||
startupLog.info("Guardrail registry initialized");
|
||||
startupLog.info("Builtin skill handlers registered");
|
||||
|
||||
// Load active plugins on startup so they survive restarts
|
||||
try {
|
||||
const { pluginManager } = await import("./lib/plugins/manager");
|
||||
await pluginManager.loadAll();
|
||||
startupLog.info("Plugin manager loaded active plugins");
|
||||
} catch (err) {
|
||||
startupLog.warn({ err }, "Plugin manager loadAll failed (non-fatal)");
|
||||
}
|
||||
|
||||
await initializeCloudSync();
|
||||
// register() only persists the definition; startAll() is what arms the timers.
|
||||
// This path does not call ensureCloudSyncInitialized(), so nothing else here
|
||||
// would start the jobs on our behalf. It registers the same set as that path:
|
||||
// starting one job and not the other is how a background job goes missing
|
||||
// without anything failing.
|
||||
const { getJobRegistry } = await import("./lib/jobRegistry");
|
||||
const jobRegistry = getJobRegistry();
|
||||
registerBudgetResetJob(jobRegistry);
|
||||
registerTokenHealthCheck(jobRegistry);
|
||||
await jobRegistry.startAll();
|
||||
startReasoningCacheCleanupJob();
|
||||
startCleanupScheduler();
|
||||
startRuntimeConfigHotReload();
|
||||
startupLog.info("Server started with cloud sync initialized");
|
||||
|
||||
// Log server start event to audit log
|
||||
logAuditEvent({
|
||||
action: "server.start",
|
||||
actor: "system",
|
||||
target: "server-runtime",
|
||||
resourceType: "maintenance",
|
||||
status: "success",
|
||||
details: { timestamp: new Date().toISOString() },
|
||||
});
|
||||
} catch (error) {
|
||||
startupLog.error({ err: error }, "Error initializing cloud sync");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Pricing sync: opt-in external pricing data (non-blocking, never fatal)
|
||||
if (process.env.PRICING_SYNC_ENABLED === "true") {
|
||||
try {
|
||||
const { initPricingSync } = await import("./lib/pricingSync");
|
||||
await initPricingSync();
|
||||
} catch (err) {
|
||||
startupLog.warn({ error: getErrorMessage(err) }, "Pricing sync could not initialize");
|
||||
}
|
||||
}
|
||||
|
||||
// Arena ELO sync: model intelligence from leaderboard data (non-blocking, never fatal).
|
||||
// On by default; opt out with Dashboard Feature Flags or ARENA_ELO_SYNC_ENABLED=false.
|
||||
try {
|
||||
const { initArenaEloSync } = await import("./lib/arenaEloSync");
|
||||
await initArenaEloSync();
|
||||
} catch (err) {
|
||||
startupLog.warn({ error: getErrorMessage(err) }, "Arena ELO sync could not initialize");
|
||||
}
|
||||
|
||||
// Radar daily feed sync: only arms itself when RADAR_ENABLED AND the user
|
||||
// opt-in are already on (a flag-off boot stays timer-free — Radar inertia
|
||||
// contract). Non-blocking, never fatal.
|
||||
try {
|
||||
const { initRadarSyncScheduler } = await import("./lib/radar/scheduler");
|
||||
initRadarSyncScheduler();
|
||||
} catch (err) {
|
||||
startupLog.warn({ error: getErrorMessage(err) }, "Radar sync scheduler could not initialize");
|
||||
}
|
||||
}
|
||||
|
||||
// Start the server initialization
|
||||
startServer().catch((err) => {
|
||||
startupLog.error({ err }, "Server initialization failed");
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Export for use as module if needed
|
||||
export default startServer;
|
||||
@@ -46,32 +46,12 @@ function listProjectFiles(relPath: string): string[] {
|
||||
}
|
||||
|
||||
// ─── Pipeline Wiring ─────────────────────────────────
|
||||
|
||||
describe("Pipeline Wiring — server-init.ts", () => {
|
||||
const src = readProjectFile("src/server-init.ts");
|
||||
|
||||
it("should initialize compliance audit log", () => {
|
||||
assert.ok(src, "src/server-init.ts should exist");
|
||||
assert.match(src, /initAuditLog/);
|
||||
});
|
||||
|
||||
it("should cleanup expired logs", () => {
|
||||
assert.match(src, /cleanupExpiredLogs/);
|
||||
});
|
||||
|
||||
it("should enforce web runtime env before startup", () => {
|
||||
assert.match(src, /enforceWebRuntimeEnv/);
|
||||
});
|
||||
|
||||
it("should log server.start audit event", () => {
|
||||
assert.match(src, /server\.start/);
|
||||
});
|
||||
|
||||
it("should use the structured startup logger instead of direct console calls", () => {
|
||||
assert.match(src, /createLogger\("server-init"\)/);
|
||||
assert.doesNotMatch(src, /console\.(log|warn|error|info|debug)\(/);
|
||||
});
|
||||
});
|
||||
//
|
||||
// src/server-init.ts was removed: it was never imported anywhere and duplicated
|
||||
// the wiring below, which is the boot path that actually runs (Next.js
|
||||
// instrumentation hook). See tests/unit/credential-health-boot-wiring.test.ts and
|
||||
// tests/unit/thinking-budget-boot-wiring-5312.test.ts for the incidents that
|
||||
// wiring into the dead module caused.
|
||||
|
||||
describe("Pipeline Wiring — instrumentation-node.ts", () => {
|
||||
const src = readProjectFile("src/instrumentation-node.ts");
|
||||
|
||||
@@ -67,16 +67,19 @@ test("cleanup: has background scheduler (startCleanupScheduler)", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("cleanup: scheduler is wired into server-init.ts", () => {
|
||||
const serverInitPath = path.resolve(import.meta.dirname, "../../src/server-init.ts");
|
||||
const serverInit = fs.readFileSync(serverInitPath, "utf-8");
|
||||
test("cleanup: scheduler is wired into instrumentation-node.ts", () => {
|
||||
const instrumentationPath = path.resolve(
|
||||
import.meta.dirname,
|
||||
"../../src/instrumentation-node.ts"
|
||||
);
|
||||
const instrumentation = fs.readFileSync(instrumentationPath, "utf-8");
|
||||
assert.ok(
|
||||
serverInit.includes('import { startCleanupScheduler } from "./lib/db/cleanup"'),
|
||||
"server-init.ts must import startCleanupScheduler"
|
||||
instrumentation.includes("startCleanupScheduler"),
|
||||
"instrumentation-node.ts must import startCleanupScheduler"
|
||||
);
|
||||
assert.ok(
|
||||
serverInit.includes("startCleanupScheduler()"),
|
||||
"server-init.ts must call startCleanupScheduler() at startup"
|
||||
instrumentation.includes("startCleanupScheduler()"),
|
||||
"instrumentation-node.ts must call startCleanupScheduler() at startup"
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -34,28 +34,16 @@ test("initCloudSync: cloud sync is initialised before the registry starts any jo
|
||||
);
|
||||
});
|
||||
|
||||
test("server-init: cloud sync is initialised before the registry starts any job", () => {
|
||||
const source = readSource("src/server-init.ts");
|
||||
const initCall = source.indexOf("await initializeCloudSync(");
|
||||
const startAllCall = source.indexOf("jobRegistry.startAll(");
|
||||
|
||||
assert.notEqual(initCall, -1, "initializeCloudSync() call not found");
|
||||
assert.notEqual(startAllCall, -1, "jobRegistry.startAll() call not found");
|
||||
assert.ok(initCall < startAllCall, "startAll() must come after initializeCloudSync()");
|
||||
});
|
||||
|
||||
test("both boot paths register the same jobs", () => {
|
||||
for (const relativePath of ["src/lib/initCloudSync.ts", "src/server-init.ts"]) {
|
||||
const source = readSource(relativePath);
|
||||
assert.match(
|
||||
source,
|
||||
/registerBudgetResetJob\s*\(/,
|
||||
`${relativePath} must register the budget reset job`
|
||||
);
|
||||
assert.match(
|
||||
source,
|
||||
/registerTokenHealthCheck\s*\(/,
|
||||
`${relativePath} must register the token health check job`
|
||||
);
|
||||
}
|
||||
test("initCloudSync: both budget and token-health jobs are registered", () => {
|
||||
const source = readSource("src/lib/initCloudSync.ts");
|
||||
assert.match(
|
||||
source,
|
||||
/registerBudgetResetJob\s*\(/,
|
||||
"src/lib/initCloudSync.ts must register the budget reset job"
|
||||
);
|
||||
assert.match(
|
||||
source,
|
||||
/registerTokenHealthCheck\s*\(/,
|
||||
"src/lib/initCloudSync.ts must register the token health check job"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* boot — `_config` resets to DEFAULT (passthrough) on every process start.
|
||||
*
|
||||
* Fix: `hydrateThinkingBudgetConfig(settings)` (open-sse/services/thinkingBudget.ts),
|
||||
* called once during server bootstrap (src/server-init.ts), restores the persisted
|
||||
* called once during server bootstrap (src/instrumentation-node.ts), restores the
|
||||
* mode. This test seeds the setting through the real settings DB round-trip, runs
|
||||
* the hydrator, and asserts the in-memory config reflects the operator's choice.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user