Skip to content

Commit 0c55df9

Browse files
committed
Skip Named Pipe server startup if pipe already exists
1 parent 4d20604 commit 0c55df9

2 files changed

Lines changed: 83 additions & 8 deletions

File tree

.github/workflows/cross-platform-test.yml

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,32 @@ jobs:
309309
if ($IsWindows) {
310310
$pipeReady = Test-Path "\\.\pipe\$pipeName"
311311
} else {
312-
$pipeReady = Test-Path "/tmp/CoreFxPipe_$pipeName"
312+
# Check both /tmp and $TMPDIR on macOS/Linux
313+
$pipeReady = (Test-Path "/tmp/CoreFxPipe_$pipeName") -or
314+
($env:TMPDIR -and (Test-Path "$env:TMPDIR/CoreFxPipe_$pipeName"))
313315
}
314316
if ($pipeReady) {
315317
Write-Host "Named Pipe ready after $($i * 500)ms"
318+
319+
# Debug: Show pipe details
320+
if ($IsWindows) {
321+
Write-Host "=== Windows Named Pipes matching pattern ===" -ForegroundColor Cyan
322+
Get-ChildItem "\\.\pipe\" -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "PowerShell|MCP|Communication" } | ForEach-Object { Write-Host " $($_.Name)" }
323+
Write-Host "=== All pipes with our name ===" -ForegroundColor Cyan
324+
$pipes = Get-ChildItem "\\.\pipe\" -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq $pipeName }
325+
Write-Host " Found $($pipes.Count) pipe(s) named '$pipeName'"
326+
} else {
327+
Write-Host "=== macOS/Linux: TMPDIR and pipe locations ===" -ForegroundColor Cyan
328+
Write-Host " TMPDIR: $env:TMPDIR"
329+
Write-Host " Checking /tmp..."
330+
bash -c "ls -la /tmp/CoreFxPipe_* 2>/dev/null || echo ' No CoreFxPipe files in /tmp'"
331+
if ($env:TMPDIR) {
332+
Write-Host " Checking TMPDIR..."
333+
bash -c "ls -la `$TMPDIR/CoreFxPipe_* 2>/dev/null || echo ' No CoreFxPipe files in TMPDIR'"
334+
}
335+
Write-Host "=== lsof for background pwsh ===" -ForegroundColor Cyan
336+
bash -c "lsof -p $($bgProcess.Id) 2>/dev/null | grep -E 'unix|PIPE|sock' | head -10 || echo ' No matching descriptors'"
337+
}
316338
break
317339
}
318340
@@ -329,15 +351,22 @@ jobs:
329351
330352
# Debug: List pipe-related files and sockets
331353
if (-not $IsWindows) {
354+
Write-Host "=== Environment ===" -ForegroundColor Yellow
355+
Write-Host " TMPDIR: $env:TMPDIR"
332356
Write-Host "=== /tmp pipe files (PowerShell) ===" -ForegroundColor Yellow
333357
Get-ChildItem /tmp -Filter "CoreFxPipe_*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName }
334358
Write-Host "=== /tmp (native ls) ===" -ForegroundColor Yellow
335359
bash -c "ls -la /tmp/ | grep -i 'corefx\|pipe\|mcp\|communication' || echo 'No matching files'"
336360
bash -c "ls -la /tmp/ | head -20"
361+
if ($env:TMPDIR) {
362+
Write-Host "=== TMPDIR contents ===" -ForegroundColor Yellow
363+
bash -c "ls -la $env:TMPDIR/ 2>/dev/null | grep -i 'corefx\|pipe\|mcp' || echo 'No matching files in TMPDIR'"
364+
bash -c "ls -la $env:TMPDIR/ 2>/dev/null | head -20"
365+
}
337366
Write-Host "=== lsof for background pwsh ===" -ForegroundColor Yellow
338-
bash -c "lsof -p $($bgProcess.Id) 2>/dev/null | grep -i 'unix\|pipe\|socket' | head -20 || echo 'No sockets found'"
367+
bash -c "lsof -p $($bgProcess.Id) 2>/dev/null | grep -iE 'unix|pipe|socket|stream' | head -20 || echo 'No sockets found'"
339368
Write-Host "=== All CoreFx sockets (find) ===" -ForegroundColor Yellow
340-
bash -c "find /tmp /var/folders -name '*CoreFx*' -o -name '*PowerShell*' 2>/dev/null | head -10 || echo 'None found'"
369+
bash -c "find /tmp \$TMPDIR /var/folders -name '*CoreFx*' -o -name '*Communication*' 2>/dev/null | head -20 || echo 'None found'"
341370
}
342371
343372
# Kill process first, then read outputs

PowerShell.MCP/MCPModuleInitializer.cs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,67 @@ public class MCPModuleInitializer : IModuleAssemblyInitializer
3333

3434
public void OnImport()
3535
{
36-
// TODO: Fail module import if named pipe already exists
37-
// Throw exception?
38-
3936
try
4037
{
38+
// Check if Named Pipe already exists (another pwsh session is running)
39+
bool pipeExists = false;
40+
41+
if (OperatingSystem.IsWindows())
42+
{
43+
// On Windows, try to connect briefly to check if pipe exists
44+
try
45+
{
46+
using var testClient = new System.IO.Pipes.NamedPipeClientStream(".", NamedPipeServer.PipeName, System.IO.Pipes.PipeDirection.InOut);
47+
testClient.Connect(100); // 100ms timeout
48+
pipeExists = true;
49+
Console.Error.WriteLine($"[DEBUG] Named Pipe '{NamedPipeServer.PipeName}' already exists (connected successfully)");
50+
}
51+
catch (TimeoutException)
52+
{
53+
// Pipe exists but no server is listening yet - this is OK, we can try to be the server
54+
pipeExists = false;
55+
}
56+
catch (System.IO.IOException)
57+
{
58+
// Pipe doesn't exist or connection failed
59+
pipeExists = false;
60+
}
61+
}
62+
else
63+
{
64+
// On Linux/macOS, check for the socket file
65+
string pipePath = $"/tmp/CoreFxPipe_{NamedPipeServer.PipeName}";
66+
pipeExists = File.Exists(pipePath);
67+
if (pipeExists)
68+
{
69+
Console.Error.WriteLine($"[DEBUG] Named Pipe socket exists at {pipePath}");
70+
}
71+
}
72+
73+
if (pipeExists)
74+
{
75+
Console.Error.WriteLine("[DEBUG] Named Pipe already exists, skipping server start");
76+
77+
// Still load the polling script for other functionality
78+
var pollingScript = EmbeddedResourceLoader.LoadScript("MCPPollingEngine.ps1");
79+
using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace))
80+
{
81+
ps.AddScript(pollingScript);
82+
ps.Invoke();
83+
}
84+
return;
85+
}
86+
4187
_tokenSource = new CancellationTokenSource();
4288
_namedPipeServer = new NamedPipeServer();
4389

4490
// Load and execute MCP polling engine script
45-
var pollingScript = EmbeddedResourceLoader.LoadScript("MCPPollingEngine.ps1");
91+
var pollingScriptMain = EmbeddedResourceLoader.LoadScript("MCPPollingEngine.ps1");
4692

4793
// Execute as ScriptBlock for PowerShell execution
4894
using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace))
4995
{
50-
ps.AddScript(pollingScript);
96+
ps.AddScript(pollingScriptMain);
5197
ps.Invoke();
5298
}
5399

0 commit comments

Comments
 (0)