Files
ai-showcase-platform/lib/database-shutdown-manager.ts

214 lines
6.3 KiB
TypeScript

// =====================================================
// 資料庫關閉管理器
// =====================================================
import { db } from './database';
import { dbFailover } from './database-failover';
import { dbMonitor } from './database-monitor';
import { connectionMonitor } from './connection-monitor';
export class DatabaseShutdownManager {
private static instance: DatabaseShutdownManager;
private isShuttingDown = false;
private shutdownHandlers: (() => Promise<void>)[] = [];
private constructor() {
this.registerShutdownHandlers();
}
public static getInstance(): DatabaseShutdownManager {
if (!DatabaseShutdownManager.instance) {
DatabaseShutdownManager.instance = new DatabaseShutdownManager();
}
return DatabaseShutdownManager.instance;
}
// 註冊關閉處理器
private registerShutdownHandlers() {
// 添加資料庫關閉處理器
this.addShutdownHandler('database', async () => {
console.log('🔄 正在關閉主要資料庫連線池...');
try {
await db.close();
console.log('✅ 主要資料庫連線池已關閉');
} catch (error) {
console.error('❌ 關閉主要資料庫連線池時發生錯誤:', error);
}
});
// 添加備援資料庫關閉處理器
this.addShutdownHandler('failover', async () => {
console.log('🔄 正在關閉備援資料庫連線池...');
try {
await dbFailover.close();
console.log('✅ 備援資料庫連線池已關閉');
} catch (error) {
console.error('❌ 關閉備援資料庫連線池時發生錯誤:', error);
}
});
// 添加監控服務關閉處理器
this.addShutdownHandler('monitor', async () => {
console.log('🔄 正在停止資料庫監控服務...');
try {
dbMonitor.stopMonitoring();
console.log('✅ 資料庫監控服務已停止');
} catch (error) {
console.error('❌ 停止資料庫監控服務時發生錯誤:', error);
}
});
// 添加連線監控關閉處理器
this.addShutdownHandler('connection-monitor', async () => {
console.log('🔄 正在停止連線監控服務...');
try {
connectionMonitor.stopMonitoring();
console.log('✅ 連線監控服務已停止');
} catch (error) {
console.error('❌ 停止連線監控服務時發生錯誤:', error);
}
});
// 註冊系統信號處理器
this.registerSystemHandlers();
}
// 添加關閉處理器
public addShutdownHandler(name: string, handler: () => Promise<void>) {
this.shutdownHandlers.push(async () => {
try {
console.log(`🔄 執行關閉處理器: ${name}`);
await handler();
console.log(`✅ 關閉處理器完成: ${name}`);
} catch (error) {
console.error(`❌ 關閉處理器失敗: ${name}`, error);
}
});
}
// 初始化服務
public initialize(): void {
console.log('🚀 初始化資料庫服務...');
// 啟動連線監控
try {
connectionMonitor.startMonitoring(30000); // 30秒檢查一次
console.log('✅ 連線監控已啟動');
} catch (error) {
console.error('❌ 啟動連線監控失敗:', error);
}
console.log('✅ 資料庫服務初始化完成');
}
// 註冊系統信號處理器
private registerSystemHandlers() {
if (typeof process === 'undefined') return;
// SIGINT (Ctrl+C)
process.on('SIGINT', () => {
console.log('\n🛑 收到 SIGINT 信號,開始優雅關閉...');
this.gracefulShutdown();
});
// SIGTERM (終止信號)
process.on('SIGTERM', () => {
console.log('\n🛑 收到 SIGTERM 信號,開始優雅關閉...');
this.gracefulShutdown();
});
// 未捕獲的異常
process.on('uncaughtException', (error) => {
console.error('❌ 未捕獲的異常:', error);
this.gracefulShutdown();
});
// 未處理的 Promise 拒絕
process.on('unhandledRejection', (reason, promise) => {
console.error('❌ 未處理的 Promise 拒絕:', reason);
this.gracefulShutdown();
});
// 程序退出
process.on('exit', () => {
if (!this.isShuttingDown) {
console.log('🛑 程序即將退出,強制關閉資料庫連線...');
this.forceShutdown();
}
});
console.log('✅ 系統信號處理器已註冊');
}
// 優雅關閉
public async gracefulShutdown() {
if (this.isShuttingDown) {
console.log('⚠️ 關閉程序已在進行中,跳過重複請求');
return;
}
this.isShuttingDown = true;
console.log('🔄 開始優雅關閉資料庫連線...');
const startTime = Date.now();
try {
// 並行執行所有關閉處理器
await Promise.allSettled(
this.shutdownHandlers.map(handler => handler())
);
const duration = Date.now() - startTime;
console.log(`✅ 資料庫連線關閉完成,耗時: ${duration}ms`);
} catch (error) {
console.error('❌ 優雅關閉過程中發生錯誤:', error);
} finally {
// 強制退出程序
setTimeout(() => {
console.log('🛑 強制退出程序');
process.exit(0);
}, 5000); // 5秒後強制退出
}
}
// 強制關閉
public forceShutdown() {
console.log('🚨 強制關閉所有資料庫連線...');
// 同步執行關閉處理器(不等待)
this.shutdownHandlers.forEach(handler => {
try {
handler();
} catch (error) {
console.error('❌ 強制關閉時發生錯誤:', error);
}
});
console.log('✅ 強制關閉完成');
}
// 獲取關閉狀態
public getShutdownStatus() {
return {
isShuttingDown: this.isShuttingDown,
handlerCount: this.shutdownHandlers.length,
registeredHandlers: this.shutdownHandlers.map((_, index) => `handler-${index}`)
};
}
// 測試關閉機制
public async testShutdown() {
console.log('🧪 測試資料庫關閉機制...');
await this.gracefulShutdown();
}
}
// 導出單例實例
export const dbShutdownManager = DatabaseShutdownManager.getInstance();
// 導出便捷函數
export const gracefulShutdown = () => dbShutdownManager.gracefulShutdown();
export const forceShutdown = () => dbShutdownManager.forceShutdown();