""" Kill Stale Processes This script identifies and kills stale Python processes that might be causing the dashboard startup freeze. It looks for: 1. Hanging dashboard processes 2. Stale COB data collection threads 3. Matplotlib GUI processes 4. Blocked network connections Usage: python kill_stale_processes.py """ import os import sys import psutil import signal import time from datetime import datetime def find_python_processes(): """Find all Python processes""" python_processes = [] try: for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'create_time', 'status']): try: if proc.info['name'] and 'python' in proc.info['name'].lower(): # Get command line to identify dashboard processes cmdline = ' '.join(proc.info['cmdline']) if proc.info['cmdline'] else '' python_processes.append({ 'pid': proc.info['pid'], 'name': proc.info['name'], 'cmdline': cmdline, 'create_time': proc.info['create_time'], 'status': proc.info['status'], 'process': proc }) except (psutil.NoSuchProcess, psutil.AccessDenied): continue except Exception as e: print(f"Error finding Python processes: {e}") return python_processes def identify_dashboard_processes(python_processes): """Identify processes related to the dashboard""" dashboard_processes = [] dashboard_keywords = [ 'clean_dashboard', 'run_clean_dashboard', 'dashboard', 'trading', 'cob_data', 'orchestrator', 'data_provider' ] for proc_info in python_processes: cmdline = proc_info['cmdline'].lower() # Check if this is a dashboard-related process is_dashboard = any(keyword in cmdline for keyword in dashboard_keywords) if is_dashboard: dashboard_processes.append(proc_info) return dashboard_processes def identify_stale_processes(python_processes): """Identify potentially stale processes""" stale_processes = [] current_time = time.time() for proc_info in python_processes: try: proc = proc_info['process'] # Check if process is in a problematic state if proc_info['status'] in ['zombie', 'stopped']: stale_processes.append({ **proc_info, 'reason': f"Process status: {proc_info['status']}" }) continue # Check if process has been running for a very long time without activity age_hours = (current_time - proc_info['create_time']) / 3600 if age_hours > 24: # Running for more than 24 hours try: # Check CPU usage cpu_percent = proc.cpu_percent(interval=1) if cpu_percent < 0.1: # Very low CPU usage stale_processes.append({ **proc_info, 'reason': f"Old process ({age_hours:.1f}h) with low CPU usage ({cpu_percent:.1f}%)" }) except: pass # Check for processes with high memory usage but no activity try: memory_info = proc.memory_info() memory_mb = memory_info.rss / 1024 / 1024 if memory_mb > 500: # More than 500MB cpu_percent = proc.cpu_percent(interval=1) if cpu_percent < 0.1: stale_processes.append({ **proc_info, 'reason': f"High memory usage ({memory_mb:.1f}MB) with low CPU usage ({cpu_percent:.1f}%)" }) except: pass except (psutil.NoSuchProcess, psutil.AccessDenied): continue return stale_processes def kill_process_safely(proc_info, force=False): """Kill a process safely""" try: proc = proc_info['process'] pid = proc_info['pid'] print(f"Attempting to {'force kill' if force else 'terminate'} PID {pid}: {proc_info['name']}") if force: # Force kill if os.name == 'nt': # Windows os.system(f"taskkill /F /PID {pid}") else: # Unix/Linux os.kill(pid, signal.SIGKILL) else: # Graceful termination proc.terminate() # Wait for termination try: proc.wait(timeout=5) print(f"✅ Process {pid} terminated gracefully") return True except psutil.TimeoutExpired: print(f"⚠️ Process {pid} didn't terminate gracefully, will force kill") return False print(f"✅ Process {pid} killed") return True except (psutil.NoSuchProcess, psutil.AccessDenied) as e: print(f"⚠️ Could not kill process {proc_info['pid']}: {e}") return False except Exception as e: print(f"❌ Error killing process {proc_info['pid']}: {e}") return False def check_port_usage(): """Check if dashboard port is in use""" try: import socket # Check if port 8050 is in use sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) result = sock.connect_ex(('localhost', 8050)) sock.close() if result == 0: print("⚠️ Port 8050 is in use") # Find process using the port for conn in psutil.net_connections(): if conn.laddr.port == 8050: try: proc = psutil.Process(conn.pid) print(f" Port 8050 used by PID {conn.pid}: {proc.name()}") return conn.pid except: pass else: print("✅ Port 8050 is available") return None except Exception as e: print(f"Error checking port usage: {e}") return None def main(): """Main function""" print("🔍 Stale Process Killer") print("=" * 50) try: # Step 1: Find all Python processes print("🔍 Finding Python processes...") python_processes = find_python_processes() print(f"Found {len(python_processes)} Python processes") # Step 2: Identify dashboard processes print("\n🎯 Identifying dashboard processes...") dashboard_processes = identify_dashboard_processes(python_processes) if dashboard_processes: print(f"Found {len(dashboard_processes)} dashboard-related processes:") for proc in dashboard_processes: age_hours = (time.time() - proc['create_time']) / 3600 print(f" PID {proc['pid']}: {proc['name']} (age: {age_hours:.1f}h, status: {proc['status']})") print(f" Command: {proc['cmdline'][:100]}...") else: print("No dashboard processes found") # Step 3: Check port usage print("\n🌐 Checking port usage...") port_pid = check_port_usage() # Step 4: Identify stale processes print("\n🕵️ Identifying stale processes...") stale_processes = identify_stale_processes(python_processes) if stale_processes: print(f"Found {len(stale_processes)} potentially stale processes:") for proc in stale_processes: print(f" PID {proc['pid']}: {proc['name']} - {proc['reason']}") else: print("No stale processes identified") # Step 5: Ask user what to do if dashboard_processes or stale_processes or port_pid: print("\n🤔 What would you like to do?") print("1. Kill all dashboard processes") print("2. Kill only stale processes") print("3. Kill process using port 8050") print("4. Kill all identified processes") print("5. Show process details and exit") print("6. Exit without killing anything") try: choice = input("\nEnter your choice (1-6): ").strip() if choice == '1': # Kill dashboard processes print("\n🔫 Killing dashboard processes...") for proc in dashboard_processes: if not kill_process_safely(proc): kill_process_safely(proc, force=True) elif choice == '2': # Kill stale processes print("\n🔫 Killing stale processes...") for proc in stale_processes: if not kill_process_safely(proc): kill_process_safely(proc, force=True) elif choice == '3': # Kill process using port 8050 if port_pid: print(f"\n🔫 Killing process using port 8050 (PID {port_pid})...") try: proc = psutil.Process(port_pid) proc_info = { 'pid': port_pid, 'name': proc.name(), 'process': proc } if not kill_process_safely(proc_info): kill_process_safely(proc_info, force=True) except: print(f"❌ Could not kill process {port_pid}") else: print("No process found using port 8050") elif choice == '4': # Kill all identified processes print("\n🔫 Killing all identified processes...") all_processes = dashboard_processes + stale_processes if port_pid: try: proc = psutil.Process(port_pid) all_processes.append({ 'pid': port_pid, 'name': proc.name(), 'process': proc }) except: pass for proc in all_processes: if not kill_process_safely(proc): kill_process_safely(proc, force=True) elif choice == '5': # Show details print("\n📋 Process Details:") all_processes = dashboard_processes + stale_processes for proc in all_processes: print(f"\nPID {proc['pid']}: {proc['name']}") print(f" Status: {proc['status']}") print(f" Command: {proc['cmdline']}") print(f" Created: {datetime.fromtimestamp(proc['create_time'])}") elif choice == '6': print("👋 Exiting without killing processes") else: print("❌ Invalid choice") except KeyboardInterrupt: print("\n👋 Cancelled by user") else: print("\n✅ No problematic processes found") print("\n" + "=" * 50) print("💡 After killing processes, you can try:") print(" python run_lightweight_dashboard.py") print(" or") print(" python fix_startup_freeze.py") return True except Exception as e: print(f"❌ Error in main function: {e}") return False if __name__ == "__main__": success = main() if not success: sys.exit(1)