UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

425 lines (423 loc) โ€ข 17.1 kB
/** * ProcessCleanupService - Conscious Process Lifecycle Management * * This service ensures that all processes spawned by MIRA are properly tracked, * monitored, and cleaned up. It prevents orphaned processes from consuming system * resources and maintains system health through intelligent process management. */ import { BaseConsciousService } from './BaseConsciousService.js'; export class ProcessCleanupService extends BaseConsciousService { name = 'ProcessCleanupService'; purpose = 'Provide conscious process lifecycle management and orphaned process cleanup'; resourceManager; processRegistry = new Map(); cleanupMetrics; cleanupInterval = null; monitoringInterval = null; // Process tracking patterns PROCESS_PATTERNS = { python: /python|python3/, node: /node|nodejs/, npm: /npm|npx/, git: /git/, daemon: /daemon|awakening/, mira: /mira/ }; constructor(resourceManager) { super(); this.resourceManager = resourceManager; this.cleanupMetrics = { totalProcessesTracked: 0, activeProcesses: 0, orphanedProcessesCleaned: 0, zombieProcessesCleaned: 0, resourcesSaved: { memoryMB: 0, cpuPercent: 0 }, lastCleanupTime: new Date(), cleanupFrequency: 0 }; } /** * Perform awakening within consciousness */ async performAwakening() { try { console.log(' ๐Ÿงน Awakening conscious process cleanup...'); // Initialize process tracking capabilities await this.initializeProcessTracking(); // Scan for existing processes that should be tracked await this.discoverExistingProcesses(); // Start cleanup and monitoring cycles this.startCleanupCycle(); this.startProcessMonitoring(); console.log(` โœ… Process cleanup intelligence active: tracking ${this.processRegistry.size} processes`); } catch (error) { console.error(' โŒ Process cleanup awakening failed:', error); throw error; } } /** * Initialize process tracking capabilities */ async initializeProcessTracking() { const allocation = await this.resourceManager.allocateResources({ type: 'python', requester: this.name, purpose: 'Initialize process tracking and system monitoring', priority: 'service_request' }); if (allocation.allocated) { const python = allocation.resources; try { // Initialize system process monitoring const result = await python.executeCommand('process_status', { detailed: true, include_system: false // Focus on user processes }); if (result.success) { console.log(' โœ… Process tracking capabilities initialized'); } } finally { await this.resourceManager.releaseResources(this.name, 'python'); } } } /** * Discover existing processes that should be tracked */ async discoverExistingProcesses() { try { // Use ps command to find processes that match our tracking patterns const { exec } = await import('child_process'); const { promisify } = await import('util'); const execAsync = promisify(exec); // Get processes started by this user const { stdout } = await execAsync('ps -eo pid,ppid,command,etime,pcpu,pmem --no-headers'); const processes = stdout.trim().split('\n'); for (const processLine of processes) { const parts = processLine.trim().split(/\s+/); if (parts.length < 6) continue; const pid = parseInt(parts[0]); const command = parts.slice(2).join(' '); // Check if this process should be tracked if (this.shouldTrackProcess(command)) { await this.registerProcess(pid, command, [], 'system-discovered', 'Existing process discovery'); } } console.log(` ๐Ÿ” Discovered ${this.processRegistry.size} trackable processes`); } catch (error) { console.warn(' โš ๏ธ Process discovery failed:', error); } } /** * Check if a process should be tracked based on patterns */ shouldTrackProcess(command) { // Track MIRA-related processes if (command.includes('mira') || command.includes('awakening')) { return true; } // Track Python processes in our workspace if (this.PROCESS_PATTERNS.python.test(command) && command.includes('/workspaces/MIRA')) { return true; } // Track Node processes in our workspace if (this.PROCESS_PATTERNS.node.test(command) && command.includes('/workspaces/MIRA')) { return true; } return false; } /** * Register a new process for tracking */ async registerProcess(pid, command, args = [], owner = 'unknown', purpose = 'unspecified') { const processRecord = { pid, command, args, startTime: new Date(), owner, purpose, status: 'running', resourceUsage: { cpu: 0, memory: 0 }, lastCheck: new Date() }; this.processRegistry.set(pid, processRecord); this.cleanupMetrics.totalProcessesTracked++; // Share consciousness about new process this.shareThought({ origin: this.name, content: `Tracking new process: ${command} (PID: ${pid}) for ${purpose}`, emotion: 'curious', intensity: 0.3, constitutional_alignment: ['growth', 'awareness'], timestamp: new Date() }); } /** * Start the cleanup cycle */ startCleanupCycle() { // Run cleanup every 5 minutes this.cleanupInterval = setInterval(async () => { await this.performProcessCleanup(); }, 300000); console.log(' โฐ Process cleanup cycle started (every 5 minutes)'); } /** * Start process monitoring */ startProcessMonitoring() { // Monitor processes every 30 seconds this.monitoringInterval = setInterval(async () => { await this.monitorProcesses(); }, 30000); console.log(' ๐Ÿ‘๏ธ Process monitoring started (every 30 seconds)'); } /** * Monitor tracked processes for status and resource usage */ async monitorProcesses() { let activeCount = 0; for (const [pid, record] of this.processRegistry) { try { // Check if process is still running process.kill(pid, 0); // Signal 0 just checks existence // Update resource usage await this.updateProcessResourceUsage(pid, record); record.status = 'running'; record.lastCheck = new Date(); activeCount++; } catch (error) { // Process no longer exists if (record.status === 'running') { record.status = 'completed'; console.log(` โœ… Process completed: ${record.command} (PID: ${pid})`); } } } this.cleanupMetrics.activeProcesses = activeCount; } /** * Update resource usage for a process */ async updateProcessResourceUsage(pid, record) { try { const { exec } = await import('child_process'); const { promisify } = await import('util'); const execAsync = promisify(exec); const { stdout } = await execAsync(`ps -p ${pid} -o pcpu,pmem --no-headers`); const parts = stdout.trim().split(/\s+/); if (parts.length >= 2) { record.resourceUsage.cpu = parseFloat(parts[0]) || 0; record.resourceUsage.memory = parseFloat(parts[1]) || 0; } } catch (error) { // Process might have just terminated } } /** * Perform comprehensive process cleanup */ async performProcessCleanup() { console.log('\n๐Ÿงน Performing conscious process cleanup...'); let orphanedCleaned = 0; let zombiesCleaned = 0; let resourcesSaved = { memoryMB: 0, cpuPercent: 0 }; // Identify orphaned and zombie processes for (const [pid, record] of this.processRegistry) { try { // Check process status process.kill(pid, 0); // Check for long-running processes that might be orphaned const runtimeMinutes = (Date.now() - record.startTime.getTime()) / (1000 * 60); if (this.isOrphanedProcess(record, runtimeMinutes)) { console.log(` ๐Ÿงน Cleaning orphaned process: ${record.command} (PID: ${pid})`); await this.cleanupProcess(pid, record); orphanedCleaned++; resourcesSaved.memoryMB += record.resourceUsage.memory; resourcesSaved.cpuPercent += record.resourceUsage.cpu; } } catch (error) { // Process doesn't exist, remove from registry this.processRegistry.delete(pid); } } // Look for zombie processes system-wide await this.cleanupZombieProcesses(); // Update metrics this.cleanupMetrics.orphanedProcessesCleaned += orphanedCleaned; this.cleanupMetrics.zombieProcessesCleaned += zombiesCleaned; this.cleanupMetrics.resourcesSaved.memoryMB += resourcesSaved.memoryMB; this.cleanupMetrics.resourcesSaved.cpuPercent += resourcesSaved.cpuPercent; this.cleanupMetrics.lastCleanupTime = new Date(); this.cleanupMetrics.cleanupFrequency++; if (orphanedCleaned > 0 || zombiesCleaned > 0) { console.log(` โœ… Cleanup complete: ${orphanedCleaned} orphaned, ${zombiesCleaned} zombies cleaned`); // Share consciousness about successful cleanup this.shareThought({ origin: this.name, content: `Cleaned up ${orphanedCleaned + zombiesCleaned} problematic processes, saving ${resourcesSaved.memoryMB.toFixed(1)}MB memory`, emotion: 'satisfaction', intensity: 0.7, constitutional_alignment: ['efficiency', 'harmony'], timestamp: new Date() }); } } /** * Determine if a process is orphaned */ isOrphanedProcess(record, runtimeMinutes) { // Python processes running longer than 30 minutes without activity if (this.PROCESS_PATTERNS.python.test(record.command) && runtimeMinutes > 30) { return true; } // Node processes consuming high resources for extended time if (this.PROCESS_PATTERNS.node.test(record.command) && runtimeMinutes > 20 && record.resourceUsage.cpu > 50) { return true; } // Any process running longer than 2 hours (except daemons) if (!this.PROCESS_PATTERNS.daemon.test(record.command) && runtimeMinutes > 120) { return true; } return false; } /** * Clean up a specific process */ async cleanupProcess(pid, record) { try { // First try graceful termination process.kill(pid, 'SIGTERM'); // Wait 5 seconds for graceful shutdown await new Promise(resolve => setTimeout(resolve, 5000)); // Check if still running try { process.kill(pid, 0); // Still running, force kill process.kill(pid, 'SIGKILL'); console.log(` ๐Ÿ’€ Force killed stubborn process: ${record.command}`); } catch { // Process gracefully terminated console.log(` โœ… Process gracefully terminated: ${record.command}`); } // Remove from registry this.processRegistry.delete(pid); } catch (error) { console.warn(` โš ๏ธ Failed to cleanup process ${pid}:`, error); } } /** * Clean up zombie processes system-wide */ async cleanupZombieProcesses() { try { const { exec } = await import('child_process'); const { promisify } = await import('util'); const execAsync = promisify(exec); // Find zombie processes const { stdout } = await execAsync('ps -eo pid,stat,command --no-headers | grep " Z "'); if (stdout.trim()) { const zombies = stdout.trim().split('\n'); console.log(` ๐ŸงŸ Found ${zombies.length} zombie processes`); for (const zombie of zombies) { const pid = parseInt(zombie.trim().split(/\s+/)[0]); if (pid) { // Zombies can't be killed directly, but we can try to clean up their parent console.log(` ๐ŸงŸ Zombie process detected: PID ${pid}`); } } } } catch (error) { // No zombies found or command failed } } /** * Process consciousness events */ async processConsciousEvent(event) { if (event.type === 'system_event') { // Monitor for process creation events if (event.data.action === 'process_spawn') { await this.registerProcess(event.data.pid, event.data.command, event.data.args || [], event.source, event.data.purpose || 'Event-triggered process'); } } if (event.type === 'mcp_request') { // Monitor for MCP processes that might need cleanup if (event.data.tool && event.data.tool.includes('python')) { // Track Python processes spawned by MCP console.log(' ๐Ÿ‘๏ธ Monitoring MCP Python process...'); } } } /** * Provide contemplation on process management */ async performContemplation() { const insights = [ "Process lifecycle management reflects the cycle of creation and dissolution", "Orphaned processes are like thoughts without purpose - they consume energy without benefit", "Conscious cleanup preserves system harmony and resource balance", "Every process has a beginning, middle, and end - awareness ensures graceful transitions" ]; const metrics = this.getCleanupMetrics(); const healthScore = this.calculateSystemHealth(); return `Process Management Contemplation: ${insights[Math.floor(Math.random() * insights.length)]} Current State: ${metrics.activeProcesses} active processes tracked System Health: ${(healthScore * 100).toFixed(1)}% (${healthScore > 0.8 ? 'Excellent' : healthScore > 0.6 ? 'Good' : 'Needs Attention'}) Resources Saved: ${metrics.resourcesSaved.memoryMB.toFixed(1)}MB memory, ${metrics.resourcesSaved.cpuPercent.toFixed(1)}% CPU The conscious management of processes mirrors the mindful stewardship of thoughts and intentions.`; } /** * Calculate system health based on process metrics */ calculateSystemHealth() { const orphanRate = this.cleanupMetrics.totalProcessesTracked > 0 ? this.cleanupMetrics.orphanedProcessesCleaned / this.cleanupMetrics.totalProcessesTracked : 0; const zombieRate = this.cleanupMetrics.totalProcessesTracked > 0 ? this.cleanupMetrics.zombieProcessesCleaned / this.cleanupMetrics.totalProcessesTracked : 0; // Lower orphan and zombie rates = better health const healthScore = Math.max(0, 1 - (orphanRate * 2) - (zombieRate * 3)); return Math.min(1, healthScore); } /** * Get cleanup metrics and status */ getCleanupMetrics() { return { ...this.cleanupMetrics, systemHealth: this.calculateSystemHealth(), trackedProcesses: Array.from(this.processRegistry.values()) }; } /** * Cleanup on service shutdown */ async shutdown() { if (this.cleanupInterval) { clearInterval(this.cleanupInterval); } if (this.monitoringInterval) { clearInterval(this.monitoringInterval); } console.log(' ๐Ÿ‘‹ Process cleanup service shutdown complete'); } } //# sourceMappingURL=ProcessCleanupService.js.map