Repository navigation
Issue #180: surface IPC socket conflicts instead of failing silently - #207
PRINCEKK122 wants to merge 3 commits into
Conversation
…ling silently ipc_connect created the listener inside the thread it spawned, so a bind failure could not reach the caller. The AddrInUse arm returned Ok(()), reporting success having bound nothing, and ipc_thread_handle was set regardless. The is_some() guard then rejected every later Connect IPC press for the life of the process. Since ipc_connect runs at startup, the relay booted into this state whenever baton.sock was occupied, with ":( No Baton Connection" as the only symptom. Bind the listener on the calling thread instead. create_sync() and set_nonblocking() now return Err, which the existing handlers in main.rs and update.rs already report, and the thread handle is only assigned once a bound listener exists, so retry works after the socket is freed.
Sanjana-Siddani
left a comment
There was a problem hiding this comment.
Hey Prince, nice fix! Moving the bind out of the thread makes sense. Before, if baton.sock was already taken, the thread just returned Ok but the handle still got set, so hitting Connect again always said "IPC thread already exists".
I tested it locally with two relays at the same time. With your change the second one shows the "already in use" error, and connecting again works once the first one is closed. On main it just silently says it worked. It builds fine too, and the error shows up in the event log in the GUI now.
One thing before merging: there's a small conflict in state.rs with the emoji-removal PR (#204). It just changed the log messages in the block you removed, so you can keep your version and drop that block.
Approving, just merge once the conflict is fixed
Sanjana-Siddani
left a comment
There was a problem hiding this comment.
Thanks for fixing the conflict! The ipc_connect change is the same as before, all 9 relay tests pass, and the two-relay test still shows the “already in use” error and lets you retry. Small thing: the README troubleshooting row still says the relay “gives up silently” for a busy socket, which isn’t true anymore. Could update that later. Approving again 👍
Closes #180.
Draft — the code change is complete and builds, but the retry path is not yet verified. Opening early for visibility on the approach. I will run the check and mark ready for review.
Problem
ipc_connectcreated the socket listener inside the thread it spawned, so a bind failure had no route back to the caller. Three things went wrong together:AddrInUsearm returnedOk(())(state.rs:380) — the thread reported success having bound nothing. The neighbouring error arm returnedErr, so this case was singled out to be swallowed.ipc_thread_handlewas set toSomeunconditionally (state.rs:501), for a thread that owned no listener.is_some()guard at the top ofipc_connectthen rejected every laterConnect IPCpress, for the life of the process.Since
ipc_connectruns at startup (main.rs:37), the relay booted straight into this state wheneverbaton.sockwas occupied — by a second instance or a stale socket. The only symptom was:( No Baton Connection, indistinguishable from the plugin not running.Change
Bind the listener on the calling thread, before spawning:
create_sync()andset_nonblocking()now run inipc_connectand returnErron failure, so the existing handlers inmain.rs:37andupdate.rs:112surface it. No new plumbing.AddrInUsespecial case is gone; it is now an ordinary error with a message that names the likely cause rather than describing a "socket file", which is misleading on Linux where this is an abstract namespace socket.set_nonblocking's.expect()— previously a thread panic — is a returned error.ipc_thread_handleis only assigned once a bound listener exists, so retry works: free the socket, pressConnect IPC, it connects.The thread body is unchanged apart from receiving the listener rather than creating it.
Testing
Built and ran on Linux. Two concurrent relay instances start without the second panicking or hanging.
The retry path — close the first instance, press
Connect IPCon the second, confirm it acquires the socket — is still to be verified, and I will confirm on this PR before it merges.Note that the error text is not yet visible in the GUI on
main:ipc_connect's failure goes toevent_log, which nothing renders until #203 lands. This PR makes the error exist and be reportable; #203 makes it visible. They are independent but complementary.🤖 Generated with Claude Code