param( [int] $Port = 7788, [string] $Log = "$PSScriptRoot\sc_robust.log" ) # Robust stub sidecar: survives port-in-use from a just-killed instance, and never # dies on a transient error. Test scaffolding only. function Say($msg) { for ($i = 0; $i -lt 5; $i++) { try { "$msg" | Out-File -FilePath $Log -Append -Encoding utf8; return } catch { Start-Sleep -Milliseconds 100 } } } "" | Out-File -FilePath $Log -Encoding utf8 Say "[sidecar] starting on 127.0.0.1:$Port" $listener = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Loopback, $Port) $listener.Server.SetSocketOption('Socket', 'ReuseAddress', $true) # Wait for the port to become bindable if a prior instance is still lingering. $bound = $false for ($i = 0; $i -lt 30 -and -not $bound; $i++) { try { $listener.Start(); $bound = $true } catch { Say "[sidecar] bind retry: $($_.Exception.Message)"; Start-Sleep -Seconds 1 } } if (-not $bound) { Say "[sidecar] could not bind $Port; giving up"; exit 1 } Say "[sidecar] listening" while ($true) { try { $client = $listener.AcceptTcpClient() Say "[sidecar] === shard connected ===" $reader = New-Object System.IO.StreamReader($client.GetStream()) while ($null -ne ($line = $reader.ReadLine())) { Say "[sidecar] <- $line" } Say "[sidecar] === shard disconnected ===" $client.Close() } catch { Say "[sidecar] loop error: $($_.Exception.Message)" Start-Sleep -Milliseconds 300 } }