File size: 2,655 Bytes
cffa613
 
 
 
 
 
 
7918944
cffa613
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7918944
cffa613
 
 
 
 
 
 
7918944
 
cffa613
 
 
 
 
 
 
 
7918944
cffa613
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
import sys
import time
import psutil
import subprocess
import signal

PORTS_TO_CHECK = [8000]
processes = []

def kill_process_on_port(port):
    for proc in psutil.process_iter(['pid', 'name']):
        try:
            for conn in proc.net_connections(kind='inet'):
                if conn.laddr.port == port:
                    print(f"[CLEANUP] Found process {proc.info['name']} (PID: {proc.info['pid']}) on port {port}. Terminating...")
                    proc.kill()
                    proc.wait(timeout=3)
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass

def cleanup_ports():
    print("[CLEANUP] Checking for zombied ports...")
    for port in PORTS_TO_CHECK:
        kill_process_on_port(port)

def start_background_process(args_list, name):
    print(f"[START] Launching {name} in background...")
    proc = subprocess.Popen(args_list, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    return proc

def cleanup_servers(signum=None, frame=None):
    print("\n[SHUTDOWN] Terminating background servers...")
    for proc in processes:
        try:
            proc.terminate()
            proc.wait(timeout=2)
        except Exception:
            try:
                proc.kill()
            except Exception:
                pass
    cleanup_ports()
    print("[SHUTDOWN] Complete.")
    sys.exit(0)

def main():
    signal.signal(signal.SIGINT, cleanup_servers)
    if hasattr(signal, 'SIGTERM'):
        signal.signal(signal.SIGTERM, cleanup_servers)

    cleanup_ports()
    
    python_exe = sys.executable
    
    # Launch Core Server (API + UI merged) using sys.executable -m uvicorn
    p1 = start_background_process([python_exe, "-m", "uvicorn", "src.api.server:app", "--port", "8000"], "Core API Server")
    processes.append(p1)
    
    print("[WAIT] Allowing servers to initialize (2 seconds)...")
    time.sleep(2)
    
    print("\n[EVALUATION] Starting Headless Evaluator...\n")
    if os.path.exists("metrics.jsonl"):
        open("metrics.jsonl", "w").close()
    try:
        subprocess.run([python_exe, "src/inference/evaluate.py"], check=True)
    except subprocess.CalledProcessError as e:
        print(f"[ERROR] Evaluator failed with exit code {e.returncode}")
    except KeyboardInterrupt:
        pass
    
    print("\n[EVALUATION] Finished.")
    print("[READY] Servers are still running in background. View UI at http://127.0.0.1:8000")
    print("[READY] Press Ctrl+C to shutdown completely.")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        cleanup_servers()

if __name__ == "__main__":
    main()