Skip to content

Retry daemon socket acquisition after shutdown tail - #1274

Open
sylvesterkaczmarek wants to merge 3 commits into
ros2:rollingfrom
sylvesterkaczmarek:fix-1229-daemon-socket-retry
Open

Retry daemon socket acquisition after shutdown tail#1274
sylvesterkaczmarek wants to merge 3 commits into
ros2:rollingfrom
sylvesterkaczmarek:fix-1229-daemon-socket-retry

Conversation

@sylvesterkaczmarek

@sylvesterkaczmarek sylvesterkaczmarek commented Aug 20, 2026

Copy link
Copy Markdown

Summary

Addresses the remaining failure mode in #1229.

shutdown_daemon() now waits for the XML-RPC address to become reusable, but a daemon that exits through its inactivity timeout can still stop serving before the process releases the listening socket. During that window, spawn_daemon() currently interprets EADDRINUSE as an already-running daemon and returns False.

When a spawn timeout is provided, distinguish that shutdown-tail case from a live daemon, wait for the address to become reusable, and retry the bind once.

Existing behavior is preserved when:

  • a live daemon is actually running
  • no spawn timeout was requested
  • another process wins the bind race

Testing

Added focused unit tests for:

  • an address owned by a live daemon
  • a temporarily busy shutdown-tail address
  • existing non-blocking behavior without a timeout

Did you use Generative AI?

Yes. AI was used to assist with tests.

Distinguish a live daemon from a temporarily occupied daemon address. When a spawn timeout is provided and the daemon is no longer serving, wait for the address to become reusable and retry the bind once.

Add focused tests for live-daemon, shutdown-tail, and non-blocking behavior.

Signed-off-by: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com>
@mergify

mergify Bot commented Aug 20, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@fujitatomoya fujitatomoya left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sylvesterkaczmarek did you actually try this PR with windows that reproduce the issue?

Comment thread ros2cli/ros2cli/node/daemon.py Outdated
# On Windows a daemon can stop serving before its process releases the
# listening socket. Give that shutdown tail time to finish, then retry the
# bind. Another process may win the race, in which case it owns the socket.
if not wait_for(_is_daemon_address_free, timeout):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

full-timeout stall (and possible infinite wait) when a foreign process holds the daemon port?
the daemon address is a fixed loopback port derived from ROS_DOMAIN_ID; any unrelated process can hold it.
if that happens, is_daemon_running() is false, and wait_for(_is_daemon_address_free, timeout) polls a predicate that can never become true.
the CLI blocks for the entire spawn timeout, then returns the same false the pre-PR code returned immediately though. this could be worse for UX, the module's documented timeout convention

Signed-off-by: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com>
Signed-off-by: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com>
@sylvesterkaczmarek

Copy link
Copy Markdown
Author

@sylvesterkaczmarek did you actually try this PR with windows that reproduce the issue?

Thanks. I addressed the port-owner concern by making the retry Windows-only and bounding it to a 1-second socket-release grace period rather than the caller's full or indefinite spawn timeout. I also added regression coverage for a foreign Windows port owner.

I have not reproduced the original failure on a Windows host myself, so I am not claiming that verification. I would still want Windows CI/build-farm validation before merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants