fix: disable aggressive cleanup in development mode to prevent analysis interruption

- Completely disable automatic periodic cleanup in development mode
- Disable post-analysis cleanup in development mode
- Add multiple checks for active sessions (progress tracker, recent processes, API activity)
- Increase graceful shutdown timeout from 3s to 5s
- Add conservative fallbacks to prevent premature process termination

This prevents the cleanup system from killing browser processes during active analysis,
resolving the issue where automation analysis was being interrupted by cleanup.
This commit is contained in:
mindesbunister
2025-07-21 09:35:06 +02:00
parent 71e1a64b5d
commit 920cbbd117

View File

@@ -9,6 +9,7 @@ class AggressiveCleanup {
private cleanupInterval: NodeJS.Timeout | null = null private cleanupInterval: NodeJS.Timeout | null = null
private isRunning = false private isRunning = false
private isInitialized = false private isInitialized = false
private lastApiCallTime = Date.now()
private constructor() { private constructor() {
// Don't auto-start - let startup.ts control it // Don't auto-start - let startup.ts control it
@@ -30,10 +31,11 @@ class AggressiveCleanup {
this.isInitialized = true this.isInitialized = true
console.log('🚀 Starting aggressive cleanup system') 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') { if (process.env.NODE_ENV === 'development') {
console.log('🔧 Development mode: Using on-demand cleanup (triggered after analysis)') console.log('🔧 Development mode: Automatic cleanup DISABLED to prevent analysis interference')
console.log('✅ On-demand cleanup system ready') console.log('💡 Use manual cleanup via runPostAnalysisCleanup() or forceCleanup() when needed')
console.log('✅ Manual cleanup system ready')
return return
} }
@@ -64,26 +66,51 @@ class AggressiveCleanup {
console.log(`🧹 Running ${cleanupType} cleanup for orphaned processes...`) console.log(`🧹 Running ${cleanupType} cleanup for orphaned processes...`)
try { try {
// Check for active analysis sessions // Multiple checks for active analysis sessions
let hasActiveSessions = false
// Check 1: Progress tracker
try { try {
const { progressTracker } = await import('./progress-tracker') const { progressTracker } = await import('./progress-tracker')
const activeSessions = progressTracker.getActiveSessions() const activeSessions = progressTracker.getActiveSessions()
if (activeSessions.length > 0) { if (activeSessions.length > 0) {
console.log(`⚠️ Skipping cleanup - ${activeSessions.length} active analysis sessions: ${activeSessions.join(', ')}`) console.log(`⚠️ Found ${activeSessions.length} active progress sessions: ${activeSessions.join(', ')}`)
return hasActiveSessions = true
} }
console.log('✅ No active analysis sessions, proceeding with cleanup')
} catch (importError) { } catch (importError) {
console.error('❌ Error importing progress tracker:', importError) console.log('⚠️ Could not check progress tracker, being conservative')
console.log('⚠️ Skipping cleanup due to import error') hasActiveSessions = true // Be conservative if we can't check
return
} }
// Find and kill orphaned chromium processes // Check 2: Recent browser activity (processes less than 2 minutes old)
const chromiumProcesses = await this.findChromiumProcesses() 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) { if (chromiumProcesses.length > 0) {
console.log(`Found ${chromiumProcesses.length} chromium processes, cleaning up...`) console.log(`Found ${chromiumProcesses.length} chromium processes, cleaning up...`)
@@ -93,8 +120,8 @@ class AggressiveCleanup {
// In development, use gentler SIGTERM first // In development, use gentler SIGTERM first
console.log(`🔧 Dev mode: Gentle shutdown of process ${pid}`) console.log(`🔧 Dev mode: Gentle shutdown of process ${pid}`)
await execAsync(`kill -TERM ${pid}`) await execAsync(`kill -TERM ${pid}`)
// Give process 3 seconds to shut down gracefully // Give process 5 seconds to shut down gracefully (increased from 3)
await new Promise(resolve => setTimeout(resolve, 3000)) await new Promise(resolve => setTimeout(resolve, 5000))
// Check if process is still running // Check if process is still running
try { try {
@@ -152,6 +179,33 @@ class AggressiveCleanup {
} }
} }
private async checkProcessAge(pids: string[]): Promise<string[]> {
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<void> { async forceCleanup(): Promise<void> {
console.log('🚨 Force cleanup initiated...') console.log('🚨 Force cleanup initiated...')
@@ -175,6 +229,14 @@ class AggressiveCleanup {
// New method for on-demand cleanup after analysis // New method for on-demand cleanup after analysis
async runPostAnalysisCleanup(): Promise<void> { async runPostAnalysisCleanup(): Promise<void> {
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...') console.log('🧹 Post-analysis cleanup triggered...')
// Small delay to ensure analysis processes are fully closed // Small delay to ensure analysis processes are fully closed