73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import { env } from './config/env.js';
|
|
import { db } from './db/client.js';
|
|
import { createApp } from './app.js';
|
|
import { ChatService } from './services/chat-service.js';
|
|
import { ensureChatConversationTables } from './services/chat-room-service.js';
|
|
import { shutdownNotificationProvider } from './services/notification-service.js';
|
|
import { ServerRestartReservationWorker } from './services/server-restart-reservation-service.js';
|
|
import { PlanWorker } from './workers/plan-worker.js';
|
|
|
|
const app = createApp();
|
|
const planWorker = new PlanWorker(app.log);
|
|
const serverRestartReservationWorker = new ServerRestartReservationWorker(app.log);
|
|
const chatService = new ChatService(app.log);
|
|
const startedAt = Date.now();
|
|
let shutdownPromise: Promise<void> | null = null;
|
|
app.server.on('upgrade', chatService.attachUpgradeHandler());
|
|
|
|
async function start() {
|
|
try {
|
|
await ensureChatConversationTables();
|
|
await chatService.recoverInterruptedSessions();
|
|
await app.listen({
|
|
host: '0.0.0.0',
|
|
port: env.PORT,
|
|
});
|
|
planWorker.start();
|
|
serverRestartReservationWorker.start();
|
|
} catch (error) {
|
|
app.log.error(error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
async function shutdown(signal: string) {
|
|
if (shutdownPromise) {
|
|
return shutdownPromise;
|
|
}
|
|
|
|
shutdownPromise = (async () => {
|
|
app.log.warn({
|
|
signal,
|
|
pid: process.pid,
|
|
uptimeSeconds: Math.round((Date.now() - startedAt) / 1000),
|
|
rssBytes: process.memoryUsage().rss,
|
|
}, 'Received shutdown signal');
|
|
|
|
try {
|
|
await planWorker.stop();
|
|
await serverRestartReservationWorker.stop();
|
|
chatService.close();
|
|
await app.close();
|
|
await shutdownNotificationProvider();
|
|
await db.destroy();
|
|
process.exitCode = 0;
|
|
} catch (error) {
|
|
app.log.error({ error, signal }, 'Failed to shut down cleanly');
|
|
process.exitCode = 1;
|
|
}
|
|
})();
|
|
|
|
return shutdownPromise;
|
|
}
|
|
|
|
process.on('SIGINT', () => {
|
|
void shutdown('SIGINT');
|
|
});
|
|
|
|
process.on('SIGTERM', () => {
|
|
void shutdown('SIGTERM');
|
|
});
|
|
|
|
void start();
|