Files
order_site/apps/backend/src/startup/bootstrap.ts
T
2026-05-25 22:15:35 +08:00

68 lines
2.1 KiB
TypeScript

import { runDatabaseMigrations } from "../db/migrate.js";
import { ensureAdminUsersBootstrapped } from "../services/admin/admin-auth-service.js";
import { ensureFulfillmentCatalogBootstrapped } from "../services/bootstrap/fulfillment-bootstrap-service.js";
import { startScheduledJobs } from "../services/scheduler/scheduler-service.js";
import { logError, logInfo } from "../utils/logger.js";
import { formatStartupError, type StartupState } from "./state.js";
const CORE_BOOT_RETRY_DELAY_MS = 5_000;
export async function bootstrapCoreServices(
startupState: StartupState,
isShutdownStarted: () => boolean
) {
if (startupState.core.running || isShutdownStarted()) {
return;
}
startupState.core.running = true;
while (!isShutdownStarted() && !startupState.core.ready) {
startupState.phase =
startupState.core.attemptCount === 0 ? "starting" : "retrying";
startupState.core.attemptCount += 1;
startupState.core.lastAttemptAt = new Date().toISOString();
try {
logInfo("[startup]", "开始执行快手核心启动步骤", {
attempt: startupState.core.attemptCount,
});
await runDatabaseMigrations();
await ensureFulfillmentCatalogBootstrapped();
await ensureAdminUsersBootstrapped();
startupState.core.ready = true;
startupState.core.lastError = "";
startupState.phase = "ready";
startupState.core.readyAt = new Date().toISOString();
logInfo("[startup]", "快手核心启动步骤完成,服务已就绪", {
attempt: startupState.core.attemptCount,
});
startScheduledJobs();
break;
} catch (error) {
const message = formatStartupError(error);
startupState.phase = "retrying";
startupState.core.lastError = message;
logError("[startup]", "快手核心启动步骤失败,将自动重试", {
attempt: startupState.core.attemptCount,
retryDelayMs: CORE_BOOT_RETRY_DELAY_MS,
error,
});
await sleep(CORE_BOOT_RETRY_DELAY_MS);
}
}
startupState.core.running = false;
}
function sleep(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}