Skip to main content
Glama

MCPDemo - Visual SQL Chat Platform

by Ayi456
CleanupScheduler.ts4.79 kB
import { CleanupConfig } from './types.js'; import { cleanupExpiredPanels } from './database.js'; /** * 数据库清理调度器 * 负责定期执行过期Panel的清理任务 */ export class CleanupScheduler { private config: CleanupConfig; private intervalId: NodeJS.Timeout | null = null; private isRunning: boolean = false; private lastRunTime: Date | null = null; private consecutiveFailures: number = 0; private readonly maxConsecutiveFailures = 5; constructor(config: CleanupConfig) { this.config = config; this.validateConfig(); } /** * 验证配置参数 */ private validateConfig(): void { if (this.config.intervalHours < 1) { throw new Error('清理间隔不能小于1小时'); } if (this.config.retentionDays < 1) { throw new Error('数据保留天数不能小于1天'); } if (this.config.batchSize < 100 || this.config.batchSize > 10000) { throw new Error('批量大小必须在100-10000之间'); } } /** * 启动定时清理任务 */ public start(): void { if (!this.config.enabled) { console.log('数据库清理功能已禁用'); return; } if (this.intervalId) { console.log('清理调度器已经在运行中'); return; } const intervalMs = this.config.intervalHours * 60 * 60 * 1000; console.log(`启动数据库清理调度器,间隔: ${this.config.intervalHours}小时,数据保留: ${this.config.retentionDays}天`); // 立即执行一次清理(可选) this.executeCleanup().catch(error => { console.error('初始清理执行失败:', error); }); // 设置定时器 this.intervalId = setInterval(() => { this.executeCleanup().catch(error => { console.error('定时清理执行失败:', error); }); }, intervalMs); } /** * 停止定时清理任务 */ public stop(): void { if (this.intervalId) { clearInterval(this.intervalId); this.intervalId = null; console.log('数据库清理调度器已停止'); } } /** * 手动触发清理任务 */ public async manualCleanup(): Promise<{ markedCount: number; deletedCount: number; duration: number; }> { console.log('手动触发数据库清理任务'); return await this.executeCleanup(); } /** * 执行清理任务 */ private async executeCleanup(): Promise<{ markedCount: number; deletedCount: number; duration: number; }> { // 防止并发执行 if (this.isRunning) { console.log('清理任务正在执行中,跳过本次调度'); throw new Error('清理任务正在执行中'); } // 检查连续失败次数 if (this.consecutiveFailures >= this.maxConsecutiveFailures) { console.error(`连续失败次数达到${this.maxConsecutiveFailures}次,暂停自动清理`); this.stop(); throw new Error('连续失败次数过多,已暂停自动清理'); } this.isRunning = true; const startTime = Date.now(); try { const result = await cleanupExpiredPanels( this.config.retentionDays, this.config.batchSize ); this.lastRunTime = new Date(); this.consecutiveFailures = 0; // 重置失败计数 console.log(`清理任务执行成功: 标记${result.markedCount}个,删除${result.deletedCount}个,耗时${result.duration}ms`); return result; } catch (error) { this.consecutiveFailures++; console.error(`清理任务执行失败 (第${this.consecutiveFailures}次):`, error); throw error; } finally { this.isRunning = false; } } /** * 获取调度器状态 */ public getStatus(): { enabled: boolean; running: boolean; lastRunTime: Date | null; consecutiveFailures: number; config: CleanupConfig; } { return { enabled: this.config.enabled && this.intervalId !== null, running: this.isRunning, lastRunTime: this.lastRunTime, consecutiveFailures: this.consecutiveFailures, config: { ...this.config } }; } /** * 更新配置 */ public updateConfig(newConfig: Partial<CleanupConfig>): void { const oldConfig = { ...this.config }; this.config = { ...this.config, ...newConfig }; try { this.validateConfig(); console.log('清理调度器配置已更新:', newConfig); // 如果间隔时间改变了,需要重启调度器 if (newConfig.intervalHours && newConfig.intervalHours !== oldConfig.intervalHours) { if (this.intervalId) { this.stop(); this.start(); } } } catch (error) { // 恢复旧配置 this.config = oldConfig; throw error; } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ayi456/visual-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server