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
JavaScript
/**
* 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