sync active training with UI if running
This commit is contained in:
225
kill_dashboard.py
Normal file
225
kill_dashboard.py
Normal file
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cross-platform script to kill stale Python dashboard processes.
|
||||
Works on Linux, macOS, and Windows.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
import psutil
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
# Dashboard script names to look for
|
||||
DASHBOARD_SCRIPTS = [
|
||||
'main_dashboard.py',
|
||||
'run_clean_dashboard.py',
|
||||
'web/clean_dashboard.py',
|
||||
'web/cob_realtime_dashboard.py',
|
||||
'ANNOTATE/web/app.py',
|
||||
'COBY/main.py',
|
||||
'run_integrated_rl_cob_dashboard.py',
|
||||
'run_realtime_rl_cob_trader.py',
|
||||
]
|
||||
|
||||
# Ports used by dashboards
|
||||
DASHBOARD_PORTS = [8050, 8051, 8052, 8080, 8081, 5001]
|
||||
|
||||
|
||||
def is_dashboard_process(proc):
|
||||
"""Check if a process is a dashboard process"""
|
||||
try:
|
||||
# Get process info
|
||||
cmdline = proc.cmdline()
|
||||
if not cmdline:
|
||||
return False
|
||||
|
||||
# Join command line for easier searching
|
||||
cmd_str = ' '.join(cmdline).lower()
|
||||
|
||||
# Check if it's a Python process
|
||||
if 'python' not in cmd_str:
|
||||
return False
|
||||
|
||||
# Check if it's running one of our dashboard scripts
|
||||
for script in DASHBOARD_SCRIPTS:
|
||||
script_lower = script.lower()
|
||||
if script_lower in cmd_str:
|
||||
return True
|
||||
|
||||
# Check if it's using one of our dashboard ports
|
||||
try:
|
||||
connections = proc.connections()
|
||||
for conn in connections:
|
||||
if hasattr(conn, 'laddr') and conn.laddr:
|
||||
if conn.laddr.port in DASHBOARD_PORTS:
|
||||
return True
|
||||
except (psutil.AccessDenied, psutil.NoSuchProcess):
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||||
return False
|
||||
|
||||
|
||||
def kill_process(proc, force=False):
|
||||
"""Kill a process gracefully or forcefully"""
|
||||
try:
|
||||
pid = proc.pid
|
||||
name = proc.name()
|
||||
|
||||
if force:
|
||||
# Force kill
|
||||
if sys.platform == 'win32':
|
||||
proc.kill()
|
||||
else:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
print(f" Force killed PID {pid} ({name})")
|
||||
else:
|
||||
# Graceful termination
|
||||
if sys.platform == 'win32':
|
||||
proc.terminate()
|
||||
else:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
print(f" Terminated PID {pid} ({name})")
|
||||
|
||||
return True
|
||||
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied, ProcessLookupError) as e:
|
||||
print(f" Could not kill PID {proc.pid}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def find_processes_on_ports():
|
||||
"""Find processes listening on dashboard ports"""
|
||||
port_processes = []
|
||||
|
||||
for proc in psutil.process_iter(['pid', 'name']):
|
||||
try:
|
||||
connections = proc.connections()
|
||||
for conn in connections:
|
||||
if hasattr(conn, 'laddr') and conn.laddr:
|
||||
if conn.laddr.port in DASHBOARD_PORTS and conn.status == 'LISTEN':
|
||||
port_processes.append({
|
||||
'pid': proc.pid,
|
||||
'name': proc.name(),
|
||||
'port': conn.laddr.port
|
||||
})
|
||||
except (psutil.AccessDenied, psutil.NoSuchProcess):
|
||||
pass
|
||||
|
||||
return port_processes
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("Killing Stale Dashboard Processes")
|
||||
print("=" * 60)
|
||||
|
||||
# Find dashboard processes
|
||||
dashboard_procs = []
|
||||
|
||||
print("\nScanning for dashboard processes...")
|
||||
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
||||
if is_dashboard_process(proc):
|
||||
dashboard_procs.append(proc)
|
||||
|
||||
if not dashboard_procs:
|
||||
print(" No dashboard processes found")
|
||||
else:
|
||||
print(f" Found {len(dashboard_procs)} dashboard process(es):")
|
||||
for proc in dashboard_procs:
|
||||
try:
|
||||
cmdline = ' '.join(proc.cmdline())
|
||||
print(f" - PID {proc.pid}: {cmdline[:80]}{'...' if len(cmdline) > 80 else ''}")
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
||||
print(f" - PID {proc.pid}: (access denied)")
|
||||
|
||||
# Find processes on dashboard ports
|
||||
print("\nChecking for processes on dashboard ports...")
|
||||
port_procs = find_processes_on_ports()
|
||||
|
||||
if not port_procs:
|
||||
print(" No processes found on dashboard ports")
|
||||
else:
|
||||
print(f" Found {len(port_procs)} process(es) on dashboard ports:")
|
||||
for p in port_procs:
|
||||
print(f" - PID {p['pid']} ({p['name']}) on port {p['port']}")
|
||||
# Add to kill list if not already there
|
||||
try:
|
||||
proc = psutil.Process(p['pid'])
|
||||
if proc not in dashboard_procs:
|
||||
dashboard_procs.append(proc)
|
||||
except psutil.NoSuchProcess:
|
||||
pass
|
||||
|
||||
# Kill all found processes
|
||||
if dashboard_procs:
|
||||
print("\nTerminating processes...")
|
||||
killed_count = 0
|
||||
|
||||
# First, try graceful termination
|
||||
for proc in dashboard_procs:
|
||||
if kill_process(proc, force=False):
|
||||
killed_count += 1
|
||||
|
||||
# Wait for processes to exit
|
||||
print("\nWaiting for processes to exit...")
|
||||
time.sleep(2)
|
||||
|
||||
# Force kill any remaining processes
|
||||
remaining = []
|
||||
for proc in dashboard_procs:
|
||||
try:
|
||||
if proc.is_running():
|
||||
remaining.append(proc)
|
||||
except psutil.NoSuchProcess:
|
||||
pass
|
||||
|
||||
if remaining:
|
||||
print(f"\nForce killing {len(remaining)} remaining process(es)...")
|
||||
for proc in remaining:
|
||||
kill_process(proc, force=True)
|
||||
|
||||
print(f"\n✓ Killed {killed_count} dashboard process(es)")
|
||||
else:
|
||||
print("\n✓ No processes to kill")
|
||||
|
||||
print("\nPort status:")
|
||||
for port in DASHBOARD_PORTS:
|
||||
port_free = True
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
for conn in proc.connections():
|
||||
if hasattr(conn, 'laddr') and conn.laddr:
|
||||
if conn.laddr.port == port and conn.status == 'LISTEN':
|
||||
print(f" Port {port}: IN USE by PID {proc.pid}")
|
||||
port_free = False
|
||||
break
|
||||
if not port_free:
|
||||
break
|
||||
except (psutil.AccessDenied, psutil.NoSuchProcess):
|
||||
pass
|
||||
|
||||
if port_free:
|
||||
print(f" Port {port}: FREE")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Process cleanup completed")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nInterrupted by user")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"\nError: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user