UNPKG

ai-debug-local-mcp

Version:

๐ŸŽฏ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

234 lines โ€ข 8.96 kB
/** * Startup-Aware Memory Manager * Enhanced v2.12.0 memory management with startup grace period * Prevents false positive memory pressure during server initialization */ export class StartupAwareMemoryManager { startupTime; STARTUP_GRACE_PERIOD = 60000; // 60 seconds STARTUP_MEMORY_THRESHOLD = 0.98; // Very lenient during startup NORMAL_MEMORY_THRESHOLD = 0.92; // Realistic threshold for normal operation STARTUP_MB_THRESHOLD = 1024; // Very lenient MB threshold during startup NORMAL_MB_THRESHOLD = 512; // Realistic MB threshold for normal operation // Anti-thrashing protection lastCleanupTime = 0; cleanupAttempts = 0; MIN_CLEANUP_INTERVAL = 30000; // 30 seconds between cleanups MAX_CLEANUP_ATTEMPTS = 3; // Max attempts before backing off constructor() { this.startupTime = Date.now(); console.log('๐Ÿš€ Startup-aware memory manager initialized'); } /** * Check if we're still in startup grace period */ isInStartupGracePeriod() { return (Date.now() - this.startupTime) < this.STARTUP_GRACE_PERIOD; } /** * Get appropriate thresholds based on startup state */ getMemoryThresholds() { if (this.isInStartupGracePeriod()) { return { heapThreshold: this.STARTUP_MEMORY_THRESHOLD, mbThreshold: this.STARTUP_MB_THRESHOLD }; } return { heapThreshold: this.NORMAL_MEMORY_THRESHOLD, mbThreshold: this.NORMAL_MB_THRESHOLD }; } /** * Intelligent memory pressure detection with startup awareness */ checkMemoryPressure() { const current = process.memoryUsage(); const heapUsageRatio = current.heapUsed / current.heapTotal; const heapUsedMB = current.heapUsed / 1024 / 1024; const thresholds = this.getMemoryThresholds(); const inStartup = this.isInStartupGracePeriod(); const stats = { heapUsed: Math.round(heapUsedMB), heapTotal: Math.round(current.heapTotal / 1024 / 1024), heapPercent: Math.round(heapUsageRatio * 100), external: Math.round(current.external / 1024 / 1024), inStartupGracePeriod: inStartup, thresholds: { heap: Math.round(thresholds.heapThreshold * 100), mb: thresholds.mbThreshold } }; // Critical memory pressure (immediate action needed) if (heapUsageRatio > 0.98 || heapUsedMB > 1024) { return { isUnderPressure: true, reason: `Critical memory usage: ${stats.heapPercent}% (${stats.heapUsed}MB)`, action: 'emergency', stats }; } // High memory pressure (cleanup needed) if (heapUsageRatio > thresholds.heapThreshold || heapUsedMB > thresholds.mbThreshold) { const action = inStartup ? 'monitor' : 'cleanup'; return { isUnderPressure: true, reason: inStartup ? `Startup memory spike: ${stats.heapPercent}% (grace period active)` : `Memory pressure: ${stats.heapPercent}% (${stats.heapUsed}MB)`, action, stats }; } // Normal operation return { isUnderPressure: false, reason: `Normal usage: ${stats.heapPercent}% (${stats.heapUsed}MB)`, action: 'none', stats }; } /** * Smart memory management action dispatcher with anti-thrashing protection */ async handleMemoryPressure() { const result = this.checkMemoryPressure(); const now = Date.now(); // Anti-thrashing: prevent excessive cleanup attempts if ((result.action === 'cleanup' || result.action === 'emergency') && now - this.lastCleanupTime < this.MIN_CLEANUP_INTERVAL) { console.log(`โณ Cleanup skipped (${Math.round((now - this.lastCleanupTime) / 1000)}s ago, min interval: ${this.MIN_CLEANUP_INTERVAL / 1000}s)`); return; } if (this.cleanupAttempts >= this.MAX_CLEANUP_ATTEMPTS) { console.log(`๐Ÿ›‘ Cleanup attempts exhausted (${this.cleanupAttempts}/${this.MAX_CLEANUP_ATTEMPTS}) - backing off`); return; } switch (result.action) { case 'emergency': console.warn(`๐Ÿšจ ${result.reason} - Emergency cleanup required!`); this.lastCleanupTime = now; this.cleanupAttempts++; await this.performEmergencyCleanup(); break; case 'cleanup': console.warn(`โš ๏ธ ${result.reason} - Performing cleanup`); this.lastCleanupTime = now; this.cleanupAttempts++; await this.performGentleCleanup(); break; case 'monitor': console.log(`๐Ÿ‘€ ${result.reason} - Monitoring closely`); this.logMemoryStats(result.stats); // Reset cleanup attempts during stable monitoring this.cleanupAttempts = Math.max(0, this.cleanupAttempts - 1); break; default: // Normal operation - periodic logging only if (Math.random() < 0.1) { // 10% chance for periodic logging console.log(`โœ… ${result.reason}`); } // Reset cleanup attempts during normal operation this.cleanupAttempts = 0; } } /** * Gentle cleanup for normal memory pressure */ async performGentleCleanup() { console.log('๐Ÿงน Performing gentle memory cleanup...'); // Force garbage collection if available if (global.gc) { global.gc(); } // Clear any large caches or temporary data // (implementation would depend on specific cleanup targets) console.log('โœ… Gentle cleanup completed'); } /** * Emergency cleanup for critical memory situations */ async performEmergencyCleanup() { console.log('๐Ÿšจ Performing emergency memory cleanup...'); // Force garbage collection if (global.gc) { global.gc(); } // Emergency session cleanup, cache clearing, etc. // (implementation would call existing cleanup methods) console.log('โœ… Emergency cleanup completed'); } /** * Log detailed memory statistics */ logMemoryStats(stats) { console.log(`๐Ÿ“Š Memory Stats: ${stats.heapUsed}MB/${stats.heapTotal}MB (${stats.heapPercent}%) | External: ${stats.external}MB | Startup: ${stats.inStartupGracePeriod}`); } /** * Get startup time for external monitoring */ getStartupAge() { return Date.now() - this.startupTime; } /** * Force end startup grace period (for testing or manual override) */ endStartupGracePeriod() { this.startupTime = Date.now() - this.STARTUP_GRACE_PERIOD - 1000; console.log('๐Ÿ”„ Startup grace period manually ended'); } /** * Legacy compatibility: Log memory usage */ logMemoryUsage(context = 'general') { const result = this.checkMemoryPressure(); console.log(`๐Ÿ“Š Memory Statistics (${context}):`); console.log(` Heap: ${result.stats.heapUsed} MB (${result.stats.heapPercent}%)`); console.log(` Startup Grace: ${result.stats.inStartupGracePeriod}`); } /** * Legacy compatibility: Get tool loading strategy */ getToolLoadingStrategy() { const result = this.checkMemoryPressure(); if (result.action === 'emergency') { return { strategy: 'minimal', batchSize: 10, reason: 'Emergency memory pressure - loading minimal tools' }; } if (result.action === 'cleanup') { return { strategy: 'batch', batchSize: 50, reason: 'Memory pressure detected - loading tools in batches' }; } return { strategy: 'all', batchSize: 100, reason: result.reason }; } /** * Legacy compatibility: Get memory stats (simplified) */ getMemoryStats() { const result = this.checkMemoryPressure(); return { pressure: { isUnderPressure: result.isUnderPressure, heapUsedMB: result.stats.heapUsed, heapUsagePercent: result.stats.heapPercent }, sessions: { total: 0, totalMemoryMB: 0 } }; } } export default StartupAwareMemoryManager; //# sourceMappingURL=startup-aware-memory-manager.js.map