From d48cd000d3c63229cc7785af664a8d6ecc72efe9 Mon Sep 17 00:00:00 2001 From: oliver Date: Wed, 6 May 2026 11:06:18 +0800 Subject: [PATCH] fix(scripts): harden stop_netx and tweak start_netx - Add timeout around Get-NetTCPConnection to avoid hangs; filter invalid PIDs; exit 0 on completion. - Minor start_netx adjustments. Co-authored-by: Cursor --- scripts/start_netx.ps1 | 2 ++ scripts/stop_netx.ps1 | 58 ++++++++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/scripts/start_netx.ps1 b/scripts/start_netx.ps1 index 702af6d..2c6b948 100644 --- a/scripts/start_netx.ps1 +++ b/scripts/start_netx.ps1 @@ -91,6 +91,8 @@ if ($Background) { Write-Host "Log = $webLogFile" Write-Host "Err = $webErrFile" } + Write-Host "" + Write-Host "==> Background services started; this script exits (API/web keep running)." -ForegroundColor Cyan exit 0 } diff --git a/scripts/stop_netx.ps1 b/scripts/stop_netx.ps1 index ad65fef..72eddcd 100644 --- a/scripts/stop_netx.ps1 +++ b/scripts/stop_netx.ps1 @@ -10,6 +10,34 @@ $runDir = Join-Path $PSScriptRoot ".run" $pidFile = Join-Path $runDir "netx.pid" $webPidFile = Join-Path $runDir "web.pid" +function Get-ListenPids { + param([int]$LocalPort) + $ids = [System.Collections.Generic.HashSet[int]]::new() + $job = $null + try { + $job = Start-Job -ScriptBlock { + param($pt) + Get-NetTCPConnection -LocalPort $pt -State Listen -ErrorAction SilentlyContinue | + Select-Object -ExpandProperty OwningProcess -Unique + } -ArgumentList $LocalPort + $null = Wait-Job $job -Timeout 5 + foreach ($x in @(Receive-Job $job -ErrorAction SilentlyContinue)) { + try { + $n = [int]$x + if ($n -gt 4) { [void]$ids.Add($n) } + } catch {} + } + } catch { + Write-Host "[WARN] port query failed for $LocalPort : $($_.Exception.Message)" + } finally { + if ($job) { + Stop-Job $job -Force -ErrorAction SilentlyContinue + Remove-Job $job -Force -ErrorAction SilentlyContinue + } + } + @($ids) +} + Write-Host "==> Stopping netx" if (Test-Path $pidFile) { @@ -44,33 +72,35 @@ if (Test-Path $webPidFile) { Remove-Item -Path $webPidFile -Force -ErrorAction SilentlyContinue } -$listeners = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue -if ($listeners) { - $owning = $listeners | Select-Object -ExpandProperty OwningProcess -Unique - foreach ($p in $owning) { +$owningApi = @(Get-ListenPids -LocalPort $Port) +if ($owningApi.Count -gt 0) { + foreach ($procId in $owningApi) { + if ($procId -eq $PID) { continue } try { - Stop-Process -Id $p -Force:$Force -ErrorAction Stop - Write-Host "Stopped by port PID=$p" + Stop-Process -Id $procId -Force:$Force -ErrorAction Stop + Write-Host "Stopped by port PID=$procId" } catch { - Write-Host "[WARN] Failed to stop PID=$p by port" + Write-Host "[WARN] Failed to stop PID=$procId by port" } } } else { Write-Host "[INFO] No listener found on port $Port" } -$webListeners = Get-NetTCPConnection -LocalPort $WebPort -State Listen -ErrorAction SilentlyContinue -if ($webListeners) { - $webOwning = $webListeners | Select-Object -ExpandProperty OwningProcess -Unique - foreach ($p in $webOwning) { +$owningWeb = @(Get-ListenPids -LocalPort $WebPort) +if ($owningWeb.Count -gt 0) { + foreach ($procId in $owningWeb) { + if ($procId -eq $PID) { continue } try { - Stop-Process -Id $p -Force:$Force -ErrorAction Stop - Write-Host "Stopped web by port PID=$p" + Stop-Process -Id $procId -Force:$Force -ErrorAction Stop + Write-Host "Stopped web by port PID=$procId" } catch { - Write-Host "[WARN] Failed to stop web PID=$p by port" + Write-Host "[WARN] Failed to stop web PID=$procId by port" } } } else { Write-Host "[INFO] No listener found on web port $WebPort" } +Write-Host "==> netx stop finished" -ForegroundColor Green +exit 0