From e239be5bbbb71a2ef890c246592878230478a56c Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Sun, 15 Mar 2026 05:43:26 -0700 Subject: [PATCH] Review fixes: CUDA restore in finally, os._exit on Windows, taskkill /T for process tree, build-server-cuda error handling, db-init path --- backend/build_binary.py | 23 ++++++++++++----------- backend/server.py | 8 +++++++- justfile | 10 ++++++---- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/backend/build_binary.py b/backend/build_binary.py index 223170aa..cc9a85b0 100644 --- a/backend/build_binary.py +++ b/backend/build_binary.py @@ -168,17 +168,18 @@ def build_server(cuda=False): restore_cuda = True # Run PyInstaller - PyInstaller.__main__.run(args) - - # Restore CUDA torch if we swapped it out - if restore_cuda: - print("Restoring CUDA torch...") - import subprocess - subprocess.run( - [sys.executable, "-m", "pip", "install", "torch", "torchvision", "torchaudio", - "--index-url", "https://download.pytorch.org/whl/cu126", "--force-reinstall", "-q"], - check=True - ) + try: + PyInstaller.__main__.run(args) + finally: + # Restore CUDA torch if we swapped it out (even on build failure) + if restore_cuda: + print("Restoring CUDA torch...") + import subprocess + subprocess.run( + [sys.executable, "-m", "pip", "install", "torch", "torchvision", "torchaudio", + "--index-url", "https://download.pytorch.org/whl/cu126", "--force-reinstall", "-q"], + check=True + ) print(f"Binary built in {backend_dir / 'dist' / binary_name}") diff --git a/backend/server.py b/backend/server.py index 573b5081..af0d4f90 100644 --- a/backend/server.py +++ b/backend/server.py @@ -119,7 +119,13 @@ def _start_parent_watchdog(parent_pid, data_dir=None): while True: if not _is_pid_alive(parent_pid): watchdog_logger.info(f"Parent process {parent_pid} gone, shutting down server...") - os.kill(os.getpid(), signal.SIGTERM) + if sys.platform == "win32": + # sys.exit triggers SystemExit, allowing uvicorn to run + # shutdown handlers. os.kill(SIGTERM) on Windows calls + # TerminateProcess which hard-kills without cleanup. + os._exit(0) + else: + os.kill(os.getpid(), signal.SIGTERM) return time.sleep(2) diff --git a/justfile b/justfile index 7595ca3c..4a78f920 100644 --- a/justfile +++ b/justfile @@ -114,7 +114,7 @@ dev: _ensure-venv _ensure-sidecar Start-Sleep -Seconds 2; \ }; \ Write-Host "Starting Tauri desktop app..."; \ - try { Set-Location "{{ tauri_dir }}"; bun run tauri dev } finally { if ($backendJob) { Stop-Process -Id $backendJob.Id -Force -ErrorAction SilentlyContinue } } + try { Set-Location "{{ tauri_dir }}"; bun run tauri dev } finally { if ($backendJob) { taskkill /PID $backendJob.Id /T /F 2>$null | Out-Null } } # Start backend only [unix] @@ -163,7 +163,7 @@ dev-web: _ensure-venv Start-Sleep -Seconds 2; \ }; \ Write-Host "Starting web app..."; \ - try { Set-Location "{{ web_dir }}"; bun run dev } finally { if ($backendJob) { Stop-Process -Id $backendJob.Id -Force -ErrorAction SilentlyContinue } } + try { Set-Location "{{ web_dir }}"; bun run dev } finally { if ($backendJob) { taskkill /PID $backendJob.Id /T /F 2>$null | Out-Null } } # Kill all dev processes [unix] @@ -201,8 +201,10 @@ build-server: _ensure-venv # Build CUDA server binary and place in app data dir for local testing [windows] build-server-cuda: _ensure-venv + $ErrorActionPreference = "Stop"; \ $env:PATH = "{{ venv_bin }};$env:PATH"; \ & "{{ python }}" backend/build_binary.py --cuda; \ + if ($LASTEXITCODE -ne 0) { throw "build_binary.py --cuda failed with exit code $LASTEXITCODE" }; \ $dest = "$env:APPDATA/com.voicebox.app/backends"; \ New-Item -ItemType Directory -Path $dest -Force | Out-Null; \ Copy-Item "backend/dist/voicebox-server-cuda.exe" "$dest/voicebox-server-cuda.exe" -Force; \ @@ -253,11 +255,11 @@ fix: # Initialize SQLite database [unix] db-init: _ensure-venv - cd {{ backend_dir }} && {{ python }} -c "from database import init_db; init_db()" + {{ python }} -c "from backend.database import init_db; init_db()" [windows] db-init: _ensure-venv - Set-Location "{{ backend_dir }}"; & "{{ python }}" -c "from database import init_db; init_db()" + & "{{ python }}" -c "from backend.database import init_db; init_db()" # Reset database (delete + reinit) [unix]