qinglong/back/app.ts
2025-05-17 17:25:50 +08:00

97 lines
2.5 KiB
TypeScript

import 'reflect-metadata';
import compression from 'compression';
import cors from 'cors';
import express from 'express';
import helmet from 'helmet';
import { Container } from 'typedi';
import config from './config';
import Logger from './loaders/logger';
import { monitoringMiddleware } from './middlewares/monitoring';
import { type GrpcServerService } from './services/grpc';
import { type HttpServerService } from './services/http';
class Application {
private app: express.Application;
private httpServerService?: HttpServerService;
private grpcServerService?: GrpcServerService;
private isShuttingDown = false;
constructor() {
this.app = express();
}
async start() {
try {
await this.initializeDatabase();
await this.initServer();
this.setupMiddlewares();
await this.initializeServices();
this.setupGracefulShutdown();
process.send?.('ready');
} catch (error) {
Logger.error('Failed to start application:', error);
process.exit(1);
}
}
async initServer() {
const { HttpServerService } = await import('./services/http');
const { GrpcServerService } = await import('./services/grpc');
this.httpServerService = Container.get(HttpServerService);
this.grpcServerService = Container.get(GrpcServerService);
}
private async initializeDatabase() {
await require('./loaders/db').default();
}
private setupMiddlewares() {
this.app.use(helmet());
this.app.use(cors(config.cors));
this.app.use(compression());
this.app.use(monitoringMiddleware);
}
private async initializeServices() {
await this.grpcServerService?.initialize();
await require('./loaders/app').default({ app: this.app });
const server = await this.httpServerService?.initialize(
this.app,
config.port,
);
await require('./loaders/server').default({ server });
}
private setupGracefulShutdown() {
const shutdown = async () => {
if (this.isShuttingDown) return;
this.isShuttingDown = true;
Logger.info('Shutting down services...');
try {
await Promise.all([
this.grpcServerService?.shutdown(),
this.httpServerService?.shutdown(),
]);
process.exit(0);
} catch (error) {
Logger.error('Error during shutdown:', error);
process.exit(1);
}
};
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);
}
}
const app = new Application();
app.start().catch((error) => {
Logger.error('Application failed to start:', error);
process.exit(1);
});