diff --git a/scripts/stop-server.ps1 b/scripts/stop-server.ps1 index cef2519..8d7a147 100644 --- a/scripts/stop-server.ps1 +++ b/scripts/stop-server.ps1 @@ -1,11 +1,43 @@ -$ErrorActionPreference = 'Stop' +$ErrorActionPreference = 'Continue' $root = Split-Path -Parent $PSScriptRoot Set-Location -LiteralPath $root +function Out-Line($msg, $color = $null) { + if ($color) { Write-Host $msg -ForegroundColor $color } + else { Write-Host $msg } + [Console]::Out.Flush() +} + +Out-Line "" + +function Test-PortOpen($port, $timeoutMs = 350) { + $client = New-Object System.Net.Sockets.TcpClient + try { + $iar = $client.BeginConnect('127.0.0.1', $port, $null, $null) + if (-not $iar.AsyncWaitHandle.WaitOne($timeoutMs)) { return $false } + $client.EndConnect($iar) + return $true + } catch { return $false } + finally { $client.Close() } +} + +function Kill-PortOwner($port) { + Get-NetTCPConnection -State Listen -LocalPort ([int]$port) -ErrorAction SilentlyContinue | + ForEach-Object { + Out-Line " [kill] Cerrando un proceso que quedaba suelto..." Gray + try { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } catch {} + } +} + if (-not (Test-Path '.run\server.info')) { - Write-Host "" - Write-Host " [yt-scraper] no hay servidor registrado." -ForegroundColor Yellow - Write-Host "" + # Nothing registered, but maybe a stray uvicorn is listening. Sweep 8000-8100. + Out-Line " [yt-scraper] Buscando servidores que quedaron sueltos..." Cyan + $killed = 0 + foreach ($p in 8000..8100) { + if (Test-PortOpen $p 200) { Kill-PortOwner $p; $killed++ } + } + if ($killed -eq 0) { Out-Line " [ok] nada que detener." Green } else { Out-Line " [ok] servidores sueltos terminados." Green } + Out-Line "" exit 0 } @@ -14,33 +46,38 @@ $parts = $firstLine -split '\s+' $port = $parts[0] $pidv = $parts[1] -Write-Host "" -Write-Host " [yt-scraper] deteniendo servidor (PID $pidv, puerto $port)..." -ForegroundColor Cyan +Out-Line " [yt-scraper] Apagando el servidor..." Cyan -if ($pidv -and $pidv -ne 'pending') { - # Kill the process tree (uvicorn + any workers). +# Detect stale info: PID gone -> treat as "already stopped" but also kill anything on the port. +$pidAlive = $false +if ($pidv) { + $proc = Get-Process -Id ([int]$pidv) -ErrorAction SilentlyContinue + $pidAlive = $null -ne $proc +} + +if (-not $pidAlive) { + Out-Line " [info] El servidor ya estaba apagado." Yellow + Kill-PortOwner $port +} else { try { Stop-Process -Id ([int]$pidv) -Force -ErrorAction Stop } catch { - # fallback: taskkill - & taskkill /PID $pidv /T /F 2>$null | Out-Null + try { & taskkill /PID $pidv /T /F 2>$null | Out-Null } catch {} } } -# Confirm the port is freed. +# Also kill any uvicorn still listening on the registered port (worker/respawn case). +Kill-PortOwner $port + +# Confirm port freed. $freed = $false -for ($i = 0; $i -lt 10; $i++) { - try { - Invoke-WebRequest -Uri "http://localhost:$port/healthz" -UseBasicParsing -TimeoutSec 1 | Out-Null - } catch { $freed = $true; break } +for ($i = 0; $i -lt 15; $i++) { + if (-not (Test-PortOpen $port 200)) { $freed = $true; break } Start-Sleep -Milliseconds 400 } Remove-Item '.run\server.info' -Force -ErrorAction SilentlyContinue -if ($freed) { - Write-Host " [ok] puerto liberado, servidor detenido." -ForegroundColor Green -} else { - Write-Host " [warn] el puerto $port sigue ocupado; revisa procesos python." -ForegroundColor Yellow -} -Write-Host "" +if ($freed) { Out-Line " [ok] puerto liberado, servidor detenido." Green } +else { Out-Line " [warn] Algo sigue ocupando la conexion. Reinicia la PC si vuelve a pasar." Yellow } +Out-Line ""