Spaces:
Sleeping
Sleeping
| @echo off | |
| setlocal EnableExtensions DisableDelayedExpansion | |
| set "SCRIPT_DIR=%~dp0" | |
| if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%" | |
| set "REPO_ROOT=%SCRIPT_DIR%" | |
| set "FRONTEND_DIR=%REPO_ROOT%\frontend" | |
| set "DEFAULT_BACKEND_PORT=8000" | |
| set "DEFAULT_FRONTEND_PORT=3001" | |
| set "MAX_FRONTEND_SCAN=25" | |
| set "BACKEND_HEALTH_PATH=/health" | |
| set "MODE=%~1" | |
| if /I "%MODE%"=="backend" goto :backend_mode | |
| if /I "%MODE%"=="frontend" goto :frontend_mode | |
| if /I "%MODE%"=="help" goto :usage | |
| if /I "%MODE%"=="-h" goto :usage | |
| if /I "%MODE%"=="--help" goto :usage | |
| set "BACKEND_PORT=%DEFAULT_BACKEND_PORT%" | |
| set "FRONTEND_PORT=%DEFAULT_FRONTEND_PORT%" | |
| if not "%~1"=="" set "BACKEND_PORT=%~1" | |
| if not "%~2"=="" set "FRONTEND_PORT=%~2" | |
| if not exist "%REPO_ROOT%\api.py" ( | |
| echo [ERROR] api.py not found. Run this script from the repository root. | |
| exit /b 1 | |
| ) | |
| if not exist "%FRONTEND_DIR%\package.json" ( | |
| echo [ERROR] frontend\package.json not found. | |
| exit /b 1 | |
| ) | |
| set "BACKEND_ALREADY_RUNNING=0" | |
| call :is_port_in_use %BACKEND_PORT% | |
| if errorlevel 1 ( | |
| echo [INFO] Starting backend API window... | |
| start "openLLMbenchmark API" "%ComSpec%" /k call "%~f0" backend %BACKEND_PORT% | |
| call :wait_for_backend_healthy %BACKEND_PORT% | |
| if errorlevel 1 ( | |
| echo [WARN] Backend did not become healthy on port %BACKEND_PORT%. | |
| echo [WARN] Check backend window logs. Missing deps/env can cause startup failures. | |
| ) | |
| ) else ( | |
| set "BACKEND_ALREADY_RUNNING=1" | |
| echo [INFO] Backend port %BACKEND_PORT% is already in use. Reusing existing backend. | |
| call :is_backend_healthy %BACKEND_PORT% | |
| if errorlevel 1 ( | |
| echo [WARN] Port %BACKEND_PORT% is listening but %BACKEND_HEALTH_PATH% did not return API health. | |
| echo [WARN] If this is not the benchmark API, stop that process or use another backend port. | |
| ) | |
| ) | |
| set /a "SCAN_COUNT=0" | |
| :find_frontend_port | |
| call :is_port_in_use %FRONTEND_PORT% | |
| if not errorlevel 1 ( | |
| set /a "SCAN_COUNT+=1" | |
| if %SCAN_COUNT% GTR %MAX_FRONTEND_SCAN% ( | |
| echo [ERROR] Could not find a free frontend port after %MAX_FRONTEND_SCAN% attempts. | |
| echo [INFO] Try: run_local_stack.bat %BACKEND_PORT% 3100 | |
| exit /b 1 | |
| ) | |
| set /a "FRONTEND_PORT+=1" | |
| goto :find_frontend_port | |
| ) | |
| echo [INFO] Starting frontend UI window... | |
| start "openLLMbenchmark UI" "%ComSpec%" /k call "%~f0" frontend %BACKEND_PORT% %FRONTEND_PORT% | |
| timeout /t 2 /nobreak >nul | |
| call :is_port_in_use %FRONTEND_PORT% | |
| if errorlevel 1 ( | |
| echo [WARN] Frontend did not open port %FRONTEND_PORT% yet. Check the frontend window for errors. | |
| ) | |
| echo [OK] Services launched. | |
| if "%BACKEND_ALREADY_RUNNING%"=="1" ( | |
| echo [OK] Backend: reused existing instance on port %BACKEND_PORT%. | |
| ) | |
| echo [OK] API docs: http://localhost:%BACKEND_PORT%/docs | |
| echo [OK] API health: http://localhost:%BACKEND_PORT%%BACKEND_HEALTH_PATH% | |
| echo [OK] UI: http://localhost:%FRONTEND_PORT% | |
| echo. | |
| echo Optional usage: | |
| echo run_local_stack.bat ^(defaults: 8000 / 3001^) | |
| echo run_local_stack.bat 8001 3002 ^(custom ports^) | |
| echo run_local_stack.bat backend 8000 ^(backend only^) | |
| echo run_local_stack.bat frontend 8000 3001 ^(frontend only^) | |
| exit /b 0 | |
| :backend_mode | |
| set "BACKEND_PORT=%DEFAULT_BACKEND_PORT%" | |
| if not "%~2"=="" set "BACKEND_PORT=%~2" | |
| cd /d "%REPO_ROOT%" | |
| where python >nul 2>&1 | |
| if errorlevel 1 ( | |
| echo [ERROR] python is not available on PATH. | |
| exit /b 1 | |
| ) | |
| echo [INFO] Backend starting on port %BACKEND_PORT%... | |
| python -m uvicorn api:app --host 0.0.0.0 --port %BACKEND_PORT% | |
| exit /b %ERRORLEVEL% | |
| :frontend_mode | |
| set "BACKEND_PORT=%DEFAULT_BACKEND_PORT%" | |
| set "FRONTEND_PORT=%DEFAULT_FRONTEND_PORT%" | |
| if not "%~2"=="" set "BACKEND_PORT=%~2" | |
| if not "%~3"=="" set "FRONTEND_PORT=%~3" | |
| set "NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:%BACKEND_PORT%" | |
| if not exist "%FRONTEND_DIR%\package.json" ( | |
| echo [ERROR] frontend\package.json not found. | |
| exit /b 1 | |
| ) | |
| where npm >nul 2>&1 | |
| if errorlevel 1 ( | |
| echo [ERROR] npm is not available on PATH. | |
| exit /b 1 | |
| ) | |
| cd /d "%FRONTEND_DIR%" | |
| if not exist "node_modules" ( | |
| echo [INFO] Installing frontend dependencies... | |
| if exist "package-lock.json" ( | |
| call npm ci | |
| ) else ( | |
| call npm install | |
| ) | |
| if errorlevel 1 ( | |
| echo [ERROR] Frontend dependency installation failed. | |
| exit /b 1 | |
| ) | |
| ) | |
| echo [INFO] Frontend starting on port %FRONTEND_PORT%... | |
| echo [INFO] API base URL: %NEXT_PUBLIC_API_BASE_URL% | |
| call npm run dev -- -p %FRONTEND_PORT% | |
| exit /b %ERRORLEVEL% | |
| :usage | |
| echo Usage: | |
| echo run_local_stack.bat | |
| echo run_local_stack.bat [backend_port] [frontend_port] | |
| echo run_local_stack.bat backend [backend_port] | |
| echo run_local_stack.bat frontend [backend_port] [frontend_port] | |
| exit /b 0 | |
| :is_port_in_use | |
| set "PORT_TO_CHECK=%~1" | |
| powershell -NoProfile -Command ^ | |
| "$p=%PORT_TO_CHECK%; if (Get-NetTCPConnection -State Listen -LocalPort $p -ErrorAction SilentlyContinue) { exit 0 } else { exit 1 }" >nul 2>&1 | |
| exit /b %ERRORLEVEL% | |
| :is_backend_healthy | |
| set "PORT_TO_CHECK=%~1" | |
| powershell -NoProfile -Command ^ | |
| "$url='http://127.0.0.1:%PORT_TO_CHECK%%BACKEND_HEALTH_PATH%'; try { $r=Invoke-RestMethod -Uri $url -TimeoutSec 2; if ($r.status -eq 'ok') { exit 0 } } catch {}; exit 1" >nul 2>&1 | |
| exit /b %ERRORLEVEL% | |
| :wait_for_backend_healthy | |
| set "PORT_TO_CHECK=%~1" | |
| set /a "HEALTH_CHECK_COUNT=0" | |
| :wait_for_backend_healthy_loop | |
| call :is_backend_healthy %PORT_TO_CHECK% | |
| if not errorlevel 1 exit /b 0 | |
| set /a "HEALTH_CHECK_COUNT+=1" | |
| if %HEALTH_CHECK_COUNT% GEQ 20 exit /b 1 | |
| timeout /t 1 /nobreak >nul | |
| goto :wait_for_backend_healthy_loop | |