Skip to content

Stamp one sequence number per buffer-aware publication - #1079

Draft
YuanYuYuan wants to merge 4 commits into
ros2:rollingfrom
ZettaScaleLabs:upstream/d2-sequence-number
Draft

YuanYuYuan wants to merge 4 commits into
ros2:rollingfrom
ZettaScaleLabs:upstream/d2-sequence-number

Conversation

@YuanYuYuan

@YuanYuYuan YuanYuYuan commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1077. Part of #1075.

Summary

publish_buffer_aware stamped one sequence number per copy. A subscriber sees only its own copy, so it counted the other copies' numbers as lost messages. This PR stamps one number per publication, shared by all copies.

Changes

  • PublisherData::publish_buffer_aware allocates the number after serialization, just before the first put attempt.
  • A publication that makes no put attempt leaves the counter unchanged.
  • The regression test uses bounded polling. It checks endpoints, delivery, matching numbers and continuity. Boundary tests cover serialization failure and the serialized base-key path.

Before and after

base this PR
One publication, three endpoints Three numbers One shared number
Consecutive publications at one endpoint Numbers three apart Numbers one apart
Serialized endpoint has no publisher Can consume a number without a put No number allocated

Tests

Measured at d5898ec in a ROS Rolling container, five trials each. The base run uses rmw_publisher_data.cpp from dda52d6 under the same tests.

Test base this PR
EveryCopyOfAPublicationCarriesTheSameNumber Fails: copies differ, numbers skip Passes
Boundary tests Not run on base Pass

Reproduction.

The fixture uses synthetic liveliness tokens and raw Zenoh samples. It does not run message_lost callbacks and needs no GPU. ros2/rmw_zenoh#1077 reports 118 lost messages per subscriber on Lyrical 0.10.6. This run does not repeat that measurement.

Breaking Changes

None. With three endpoints, attachment numbers advance by one instead of three.

Did you use Generative AI?

Yes. Claude Sonnet 5.5 (claude-sonnet-5-5) via Claude Code was used to assist with the changes, the tests and the measurements in this PR.

publish_buffer_aware() took the next sequence number for every
endpoint copy. A subscriber only sees its own copy, so with two or
more endpoints it saw a gap on every message and reported lost
messages that were delivered.

Take one number per publication and stamp every copy with it.

Signed-off-by: yuanyuyuan <az6980522@gmail.com>
Declare liveliness tokens that announce a backend named "fake", so
that the publisher creates a per-subscriber endpoint for each of them
without a GPU. Plain Zenoh subscribers record the attachment of every
copy of a publication.

Check that all copies of one publication carry the same sequence
number and that consecutive publications advance it by one.

Signed-off-by: yuanyuyuan <az6980522@gmail.com>
@YuanYuYuan YuanYuYuan changed the title fix(rmw_zenoh_cpp): stamp one sequence number per buffer-aware publication Stamp one sequence number per buffer-aware publication Oct 14, 2026
@YuanYuYuan YuanYuYuan added the bug Something isn't working label Oct 14, 2026
The comment states what the code guarantees and no longer describes the defect. The test parses liveliness tokens by segment instead of by substring.

@mini-1235 mini-1235 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi, while reviewing the same function, I noticed a minor issue: publish_buffer_aware never emits the rmw_publish tracepoint, unlike the normal publish path.

Since this PR already touches the same function and the issue is minor, I thought it would be easier to leave a comment here rather than open a separate PR. I also left a question inline.

Comment on lines +362 to +363
auto attachment_data = rmw_zenoh_cpp::AttachmentData(
publication_sequence_number(), rmw_zenoh_cpp::get_system_time_in_ns(), entity_->copy_gid());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it make sense to call rmw_zenoh_cpp::get_system_time_in_ns() just once in this function and reuse the timestamp here and L450?

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Subscribers of a buffer-aware publisher report false message_lost events

4 participants