fix(cli show): handle EEXIST in singleton race#40779
Conversation
The losing side of the singleton handshake now reads back the holder's process pid from the socket, so `### Dashboard opened with pid <N>` is always the long-lived dashboard pid (not the short-lived spawned child that exited after losing). Also accept `EEXIST` (in addition to `EADDRINUSE`) as the "someone else got there first" signal from `server.listen()`. Two cli children arriving at `bind(2)` in lockstep can produce either error code from libuv depending on timing; treat both as a cue to retry-via-connect.
Test results for "MCP"16 failed 7054 passed, 1068 skipped Merge workflow run. |
While adding a test for the singleton behaviour, I found that sometimes the loser gets
EEXIST. It's hard to reproduce, most runs hitEADDRINUSEbecause the winner'slisten()settles before the loser arrives. You can trigger it by removing the "bindTitle" or, alternatively, by insertingawait new Promise(r => setTimeout(r, 250))right beforeserver.listen(). It'll reliably trigger the following error in one of 5 runs: