2026-04-08 11:44:24 +08:00
|
|
|
|
$ErrorActionPreference = "SilentlyContinue"
|
|
|
|
|
|
$backend = "D:\aaa\aiagent\backend"
|
|
|
|
|
|
|
|
|
|
|
|
Get-CimInstance Win32_Process | Where-Object {
|
|
|
|
|
|
$_.CommandLine -and $_.CommandLine -match "celery" -and $_.CommandLine -match "celery_app"
|
|
|
|
|
|
} | ForEach-Object {
|
|
|
|
|
|
Write-Host "Stop Celery PID $($_.ProcessId)"
|
|
|
|
|
|
Stop-Process -Id $_.ProcessId -Force
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Get-CimInstance Win32_Process | Where-Object {
|
|
|
|
|
|
$_.CommandLine -and $_.CommandLine -match "uvicorn" -and $_.CommandLine -match "app.main:app"
|
|
|
|
|
|
} | ForEach-Object {
|
|
|
|
|
|
Write-Host "Stop Uvicorn PID $($_.ProcessId)"
|
|
|
|
|
|
Stop-Process -Id $_.ProcessId -Force
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-09 21:58:53 +08:00
|
|
|
|
# 兜底:清理仍占用 8037 的监听进程(多实例会随机命中旧代码并出现 500 / 路由不一致)
|
|
|
|
|
|
for ($round = 0; $round -lt 8; $round++) {
|
|
|
|
|
|
$pids = @()
|
|
|
|
|
|
try {
|
|
|
|
|
|
$pids = @(Get-NetTCPConnection -LocalPort 8037 -State Listen -ErrorAction SilentlyContinue |
|
|
|
|
|
|
ForEach-Object { $_.OwningProcess } | Where-Object { $_ -and $_ -gt 0 } | Sort-Object -Unique)
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
if (-not $pids -or $pids.Count -eq 0) { break }
|
|
|
|
|
|
foreach ($proc in $pids) {
|
|
|
|
|
|
Write-Host "Stop port 8037 PID $proc"
|
|
|
|
|
|
Stop-Process -Id ([int]$proc) -Force -ErrorAction SilentlyContinue
|
|
|
|
|
|
}
|
|
|
|
|
|
Start-Sleep -Milliseconds 600
|
|
|
|
|
|
}
|
|
|
|
|
|
netstat -ano 2>$null | Select-String ":8037\s+.*LISTENING" | ForEach-Object {
|
|
|
|
|
|
$parts = ($_.Line -replace '\s+', ' ').Trim() -split ' '
|
|
|
|
|
|
$lpid = $parts[-1]
|
|
|
|
|
|
if ($lpid -match '^\d+$' -and [int]$lpid -gt 0) {
|
|
|
|
|
|
Write-Host "Stop port 8037 (netstat) PID $lpid"
|
|
|
|
|
|
Stop-Process -Id ([int]$lpid) -Force -ErrorAction SilentlyContinue
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-08 11:44:24 +08:00
|
|
|
|
Start-Sleep -Seconds 2
|
|
|
|
|
|
|
|
|
|
|
|
$py = Join-Path $backend "venv\Scripts\python.exe"
|
2026-04-09 21:58:53 +08:00
|
|
|
|
if ($env:SKIP_ALEMBIC -ne "1") {
|
|
|
|
|
|
Write-Host "alembic upgrade head ..."
|
|
|
|
|
|
Push-Location $backend
|
|
|
|
|
|
try {
|
|
|
|
|
|
& $py -m alembic upgrade head 2>&1 | ForEach-Object { Write-Host $_ }
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
Write-Host "alembic failed: $($_.Exception.Message)"
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
Pop-Location
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Write-Host "SKIP_ALEMBIC=1 - skipped alembic."
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 不使用 --reload:Windows 上 reload 会多进程且多次重启易残留多个 8037 监听,导致随机命中旧实例、POST 执行 500
|
|
|
|
|
|
Write-Host "Start Uvicorn :8037 (no --reload) ..."
|
2026-04-08 11:44:24 +08:00
|
|
|
|
Start-Process -FilePath $py -ArgumentList @(
|
2026-04-09 21:58:53 +08:00
|
|
|
|
"-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8037"
|
2026-04-08 11:44:24 +08:00
|
|
|
|
) -WorkingDirectory $backend -WindowStyle Minimized
|
|
|
|
|
|
|
|
|
|
|
|
Start-Sleep -Seconds 2
|
|
|
|
|
|
|
|
|
|
|
|
Write-Host "Start Celery worker ..."
|
|
|
|
|
|
Start-Process -FilePath $py -ArgumentList @(
|
|
|
|
|
|
"-m", "celery", "-A", "app.core.celery_app", "worker",
|
|
|
|
|
|
"--loglevel=info", "--pool=threads", "--concurrency=8"
|
|
|
|
|
|
) -WorkingDirectory $backend -WindowStyle Minimized
|
|
|
|
|
|
|
|
|
|
|
|
Start-Sleep -Seconds 3
|
|
|
|
|
|
try {
|
|
|
|
|
|
$r = Invoke-WebRequest -Uri "http://127.0.0.1:8037/health" -UseBasicParsing -TimeoutSec 15
|
|
|
|
|
|
Write-Host "health: $($r.Content)"
|
2026-04-09 21:58:53 +08:00
|
|
|
|
$j = $r.Content | ConvertFrom-Json
|
|
|
|
|
|
$names = @($j.PSObject.Properties.Name)
|
|
|
|
|
|
if (-not ($names -contains "checks")) {
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
Write-Host "[WARN] /health has no 'checks' field; port 8037 may not be this repo API."
|
|
|
|
|
|
Write-Host "Kill stray python/uvicorn, then: uvicorn app.main:app --host 0.0.0.0 --port 8037"
|
|
|
|
|
|
Write-Host "Or use port 8040 and set AIAGENT_API_PROXY for npm run dev (see vite.config.ts)."
|
|
|
|
|
|
Write-Host ""
|
|
|
|
|
|
}
|
2026-04-08 11:44:24 +08:00
|
|
|
|
} catch {
|
|
|
|
|
|
Write-Host "health check failed: $($_.Exception.Message)"
|
|
|
|
|
|
}
|
|
|
|
|
|
Write-Host "Done."
|