diff --git a/lib/aggressive-cleanup.ts b/lib/aggressive-cleanup.ts index 369c8e3..ca2aa4e 100644 --- a/lib/aggressive-cleanup.ts +++ b/lib/aggressive-cleanup.ts @@ -9,6 +9,7 @@ class AggressiveCleanup { private cleanupInterval: NodeJS.Timeout | null = null private isRunning = false private isInitialized = false + private lastApiCallTime = Date.now() private constructor() { // Don't auto-start - let startup.ts control it @@ -30,10 +31,11 @@ class AggressiveCleanup { this.isInitialized = true console.log('๐Ÿš€ Starting aggressive cleanup system') - // In development, use on-demand cleanup instead of periodic + // In development, completely disable automatic cleanup to prevent interference if (process.env.NODE_ENV === 'development') { - console.log('๐Ÿ”ง Development mode: Using on-demand cleanup (triggered after analysis)') - console.log('โœ… On-demand cleanup system ready') + console.log('๐Ÿ”ง Development mode: Automatic cleanup DISABLED to prevent analysis interference') + console.log('๐Ÿ’ก Use manual cleanup via runPostAnalysisCleanup() or forceCleanup() when needed') + console.log('โœ… Manual cleanup system ready') return } @@ -64,26 +66,51 @@ class AggressiveCleanup { console.log(`๐Ÿงน Running ${cleanupType} cleanup for orphaned processes...`) try { - // Check for active analysis sessions + // Multiple checks for active analysis sessions + let hasActiveSessions = false + + // Check 1: Progress tracker try { const { progressTracker } = await import('./progress-tracker') const activeSessions = progressTracker.getActiveSessions() if (activeSessions.length > 0) { - console.log(`โš ๏ธ Skipping cleanup - ${activeSessions.length} active analysis sessions: ${activeSessions.join(', ')}`) - return + console.log(`โš ๏ธ Found ${activeSessions.length} active progress sessions: ${activeSessions.join(', ')}`) + hasActiveSessions = true } - - console.log('โœ… No active analysis sessions, proceeding with cleanup') } catch (importError) { - console.error('โŒ Error importing progress tracker:', importError) - console.log('โš ๏ธ Skipping cleanup due to import error') - return + console.log('โš ๏ธ Could not check progress tracker, being conservative') + hasActiveSessions = true // Be conservative if we can't check } - // Find and kill orphaned chromium processes + // Check 2: Recent browser activity (processes less than 2 minutes old) const chromiumProcesses = await this.findChromiumProcesses() + if (chromiumProcesses.length > 0) { + const recentProcesses = await this.checkProcessAge(chromiumProcesses) + if (recentProcesses.length > 0) { + console.log(`โš ๏ธ Found ${recentProcesses.length} recent browser processes (< 2 min old)`) + hasActiveSessions = true + } + } + + // Check 3: In development, be extra conservative - only cleanup if no recent API calls + if (isDevelopment) { + const lastApiCall = this.getLastApiCallTime() + const timeSinceLastApi = Date.now() - lastApiCall + if (timeSinceLastApi < 30000) { // 30 seconds + console.log(`โš ๏ธ Recent API activity detected (${Math.round(timeSinceLastApi/1000)}s ago), skipping cleanup`) + hasActiveSessions = true + } + } + + if (hasActiveSessions) { + console.log(`โš ๏ธ Skipping cleanup - active analysis detected`) + return + } + console.log('โœ… No active analysis sessions detected, proceeding with cleanup') + + // Find and kill orphaned chromium processes if (chromiumProcesses.length > 0) { console.log(`Found ${chromiumProcesses.length} chromium processes, cleaning up...`) @@ -93,8 +120,8 @@ class AggressiveCleanup { // In development, use gentler SIGTERM first console.log(`๐Ÿ”ง Dev mode: Gentle shutdown of process ${pid}`) await execAsync(`kill -TERM ${pid}`) - // Give process 3 seconds to shut down gracefully - await new Promise(resolve => setTimeout(resolve, 3000)) + // Give process 5 seconds to shut down gracefully (increased from 3) + await new Promise(resolve => setTimeout(resolve, 5000)) // Check if process is still running try { @@ -152,6 +179,33 @@ class AggressiveCleanup { } } + private async checkProcessAge(pids: string[]): Promise { + const recentProcesses: string[] = [] + const twoMinutesAgo = Date.now() - (2 * 60 * 1000) + + for (const pid of pids) { + try { + const { stdout } = await execAsync(`ps -o lstart= -p ${pid}`) + const startTime = new Date(stdout.trim()).getTime() + if (startTime > twoMinutesAgo) { + recentProcesses.push(pid) + } + } catch (error) { + // Process might not exist anymore, skip + } + } + + return recentProcesses + } + + private getLastApiCallTime(): number { + return this.lastApiCallTime + } + + updateApiCallTime(): void { + this.lastApiCallTime = Date.now() + } + async forceCleanup(): Promise { console.log('๐Ÿšจ Force cleanup initiated...') @@ -175,6 +229,14 @@ class AggressiveCleanup { // New method for on-demand cleanup after analysis async runPostAnalysisCleanup(): Promise { + const isDevelopment = process.env.NODE_ENV === 'development' + + if (isDevelopment) { + console.log('๐Ÿ”ง Development mode: Skipping post-analysis cleanup to prevent interference') + console.log('๐Ÿ’ก Manual cleanup available via forceCleanup() if needed') + return + } + console.log('๐Ÿงน Post-analysis cleanup triggered...') // Small delay to ensure analysis processes are fully closed