70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import process from "node:process";
|
|
|
|
import { createApp } from "./app.js";
|
|
import { runtimeConfig } from "./config/runtime.js";
|
|
import { assertRuntimeConfigValid } from "./config/runtime-validation.js";
|
|
import { bootstrapCoreServices } from "./startup/bootstrap.js";
|
|
import { createShutdownController } from "./startup/shutdown.js";
|
|
import { createStartupState, formatStartupError } from "./startup/state.js";
|
|
import { logError, logInfo } from "./utils/logger.js";
|
|
|
|
const port = Number(runtimeConfig.server.port || 3000);
|
|
const host = "0.0.0.0";
|
|
const startupState = createStartupState();
|
|
|
|
let shutdownController: ReturnType<typeof createShutdownController> | null = null;
|
|
|
|
try {
|
|
assertRuntimeConfigValid(runtimeConfig);
|
|
} catch (error) {
|
|
logError("[startup]", "运行时配置校验失败,服务停止启动", error);
|
|
process.exit(1);
|
|
}
|
|
|
|
const app = createApp({
|
|
startupState,
|
|
isShutdownStarted: () => shutdownController?.isShutdownStarted() || false,
|
|
config: runtimeConfig,
|
|
});
|
|
|
|
const server = app.listen(port, host, () => {
|
|
logInfo(
|
|
"[startup]",
|
|
`order-site-backend kuaishou-lite listening on http://${host}:${port}`
|
|
);
|
|
void bootstrapCoreServices(
|
|
startupState,
|
|
() => shutdownController?.isShutdownStarted() || false
|
|
);
|
|
});
|
|
|
|
shutdownController = createShutdownController(server, startupState);
|
|
|
|
server.on("error", (error) => {
|
|
logError("[startup]", "HTTP server failed", error);
|
|
});
|
|
|
|
process.on("SIGINT", () => {
|
|
void shutdownController?.shutdown("SIGINT");
|
|
});
|
|
|
|
process.on("SIGTERM", () => {
|
|
void shutdownController?.shutdown("SIGTERM");
|
|
});
|
|
|
|
process.on("unhandledRejection", (reason) => {
|
|
startupState.process.lastUnhandledRejection = {
|
|
time: new Date().toISOString(),
|
|
message: formatStartupError(reason),
|
|
};
|
|
logError("[process]", "unhandled promise rejection", reason);
|
|
});
|
|
|
|
process.on("uncaughtException", (error) => {
|
|
startupState.process.lastUncaughtException = {
|
|
time: new Date().toISOString(),
|
|
message: formatStartupError(error),
|
|
};
|
|
logError("[process]", "uncaught exception captured", error);
|
|
});
|