Skip to content

fix(rmw_wait): deliver TRANSIENT_LOCAL latched samples to late joiners of idle publishers - #37

Merged
benaliabderrahmane merged 1 commit into
mainfrom
fix/transient-local-late-joiner-replay
Jul 20, 2026
Merged

fix(rmw_wait): deliver TRANSIENT_LOCAL latched samples to late joiners of idle publishers#37
benaliabderrahmane merged 1 commit into
mainfrom
fix/transient-local-late-joiner-replay

Conversation

@benaliabderrahmane

Copy link
Copy Markdown
Owner

Problem

A TRANSIENT_LOCAL (latched) publisher on an otherwise idle node blocks in rmw_wait with an infinite timeout. A subscriber joining later only bumps the shared-memory generation counter, which signals no file descriptor — so the top-of-wait late-joiner replay never re-runs and the late subscriber never receives the retained sample.

The existing TransientLocalReplayOnWait* tests don't catch this: they create the subscriber before calling rmw_wait, whereas the real failure needs the executor to be already blocked when the subscriber joins.

Fix

Cap the wait timeout at 200 ms in rmw_wait so the executor loops and re-checks the graph. It only ever shortens the caller's timeout (a non-blocking 0 stays 0), and returning early with nothing ready is already part of the rmw_wait contract — callers simply re-wait.

Test

Adds TransientLocalReplayReachesLateJoinerWhileWaitBlocked: the subscriber joins after the executor is already blocked in rmw_wait; a guard condition cleanly unblocks the thread on teardown so the test never hangs. Fails before the fix, passes after.

Verification

Full suite green on Jazzy — every test_rmw_* suite passes, including the 21 test_rmw_qos tests and the timing-sensitive test_rmw_wait.

…s of idle publishers

An idle publisher's executor blocks in rmw_wait with an infinite timeout, and a
subscriber joining only bumps the shared-memory generation counter (no fd fires),
so the top-of-wait late-joiner replay never re-runs and the retained sample is
never delivered. Cap the wait at 200 ms so the executor loops and re-checks the
graph. The cap only shortens the caller's timeout (a non-blocking 0 stays 0), and
an early return with nothing ready is already part of the rmw_wait contract.

Add a regression test that reproduces the ordering (subscriber joins after the
executor is already blocked in rmw_wait).
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.

1 participant