Skip to content

fix(config): pin every zenoh override against rmw_zenoh_cpp - #329

Open
YuanYuYuan wants to merge 4 commits into
mainfrom
fix/pin-config-against-rmw-zenoh-cpp
Open

fix(config): pin every zenoh override against rmw_zenoh_cpp#329
YuanYuYuan wants to merge 4 commits into
mainfrom
fix/pin-config-against-rmw-zenoh-cpp

Conversation

@YuanYuYuan

@YuanYuYuan YuanYuYuan commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

crates/hiroz/src/config.rs says it generates "rmw_zenoh_cpp compatible configs". Nothing checked that. This PR adds the check, fixes the one drift it found, and corrects three documentation claims about timeouts.

keys hiroz overrides match rmw_zenoh_cpp
router config 15 15
session config 16 16 after this PR, 15 before

The drift: queries_default_timeout was 60000 where upstream is 600000. Upstream raised it in cf09e854 for slow service servers at launch. docs/user-guide/config-advanced.md already published 600000, so the docs and the code disagreed.

Why this is not an equality check

Matching upstream is not the same as being correct.

hiroz's session listen/endpoints matched rmw_zenoh_cpp exactly. Two nodes on two hosts still delivered nothing to each other (#325). Upstream's loopback locator depends on zenoh 1.8 router relaying, and zenoh 1.9 removed it. hiroz runs 1.9. Upstream does not.

So the test asserts something weaker and more useful:

condition verdict
hiroz value equals upstream's pass
differs, and DIVERGENCES gives a non-blank reason pass
differs with no reason fail — add the reason, or change config.rs
DIVERGENCES lists a key that now matches fail — remove the entry
DIVERGENCES entry has a blank reason fail — write the reason
hiroz sets a key upstream lacks fail — dropped upstream, or misspelt

Rows four and five matter as much as row three. A stale or blank entry reads as a considered decision. It exempts the key anyway.

Important

DIVERGENCES is empty, which describes main today. #325 creates the first real divergence, so #325 must add its own entry and this test fails until it does. Merge this first, then rebase #325 onto it.

What it reads

The reference is a vendored copy of upstream's two json5 files. They are byte-identical across all five rmw_zenoh branches, so one copy serves every distro.

leg reference catches
ROS-independent Test vendored hiroz drifting from the recorded upstream
Interop tests with ROS 2 * (×4) installed rmw_zenoh_cpp that, plus the vendored copy going stale

This PR changes no workflow. Those legs already run hiroz-tests after sourcing setup.bash.

The lookup uses AMENT_PREFIX_PATH, not /opt/ros/$ROS_DISTRO. The second is Debian's layout, and this workspace also builds ROS from Nix. A second test fails if rmw_zenoh_cpp is installed and the alignment test did not select it, so the fallback cannot go silent.

What it does not cover

The test compares only the keys hiroz overrides. A key that upstream sets and hiroz leaves at zenoh's default is invisible to it.

One such key exists, and the review found it: rmw_zenoh_cpp sets queries_default_timeout to 10 minutes on the router, and hiroz keeps zenoh's 10 seconds. The settings table now says so. Covering that direction needs a second allow-list, because most remaining upstream settings are moot here — multicast keys under disabled multicast, and keys zenoh 1.9 deprecated. That is a separate change.

Commit 2 — the documented timeout is not the one that fires

docs/core-concepts/services.md said a call with no server times out after queries_default_timeout, at 10 minutes. It does not.

fact file
create_client hard-codes querier_timeout to 10 s node.rs
the builder passes it to .timeout(), which overrides the session default service.rs
that is the only construction site, and with_querier_timeout is pub(crate) no public API changes it
the action result client alone sets Duration::MAX goal and cancel clients keep 10 s

A service call times out after 10 seconds. Lowering queries_default_timeout does not change it.

Review findings, all fixed

finding fix
a blank DIVERGENCES reason still exempted drift divergence_reason rejects a blank reason, and a named check reports it
the settings table claimed 10 min for the router it says 10 s, and the note below it states the divergence
"action clients set no deadline" overstated it only the result client does; goal and cancel time out at 10 s

What fails without this

Measured on one worker. Each red case is a single-line edit, reverted before the next.

direction result
unmodified pass — 31 compared, 31 identical, 0 divergences
queries_default_timeout back to 60000 failis 60000 in hiroz and 600000 in rmw_zenoh_cpp
a DIVERGENCES entry for a key that matches failnow agree on it. Remove the entry.
a key renamed to one upstream lacks failno such key
the vendored reference mutated failis 600000 in hiroz and 12345 in rmw_zenoh_cpp

The last two rows exist because the first three would all pass if the test ignored its reference. Mutating the vendored file proves those bytes are load-bearing.

The test also asserts it compared at least 25 overrides. Zero comparisons and zero failures otherwise look alike.

One thing this PR does not do

crates/rmw-zenoh-rs/config/DEFAULT_RMW_ZENOH_SESSION_CONFIG.json5 is stale: it says multicast.enabled: true where session_overrides() sets false, and queries_default_timeout: 10000. It ships to share/rmw_zenoh_rs/config/, so it can mislead a reader.

An earlier revision of this branch deleted it, and CI caught that: crates/rmw-zenoh-rs/CMakeLists.txt installs the directory, so ament_cmake_symlink_install_directory failed. Reverted in a218346. Regenerating the file from config.rs is the fix, and is a separate change.

Breaking changes

tag what changes who is affected before → after action
BC1 a raw-session query with no explicit timeout waits 10 minutes code calling ZContext::session() and issuing its own get() 60 s → 600 s set .timeout(), or override queries_default_timeout

This changes no hiroz API path. Every query hiroz issues sets its own timeout: service.rs 10 s, node.rs 10 s, graph.rs 3 s, action result client Duration::MAX.

crates/hiroz/src/config.rs claims to generate "rmw_zenoh_cpp compatible
configs". Nothing checked it. Auditing all 31 overrides against upstream at
e95c62df287143f78bdb41c452b6bf1e257b0c0d found one that did not hold, and it
was recorded nowhere.

queries_default_timeout was 60000 where upstream is 600000. Upstream raised it
to ten minutes in cf09e854c9df17e0eb7e80ce4ab00e1b122a64e0 for slow service
servers at launch -- the case hiroz's own comment cites while setting a tenth
of it. docs/user-guide/config-advanced.md already published 600000, so the
docs and the code disagreed. Realigned, and every override now matches.

The test is not an equality check, and the reason is worth stating: hiroz's
session listen/endpoints matched upstream exactly and was still wrong, because
upstream's loopback locator leans on zenoh 1.8 router relaying that zenoh 1.9
withdrew. So it asserts instead that every difference is listed with a reason,
and that every listed reason still describes a real difference -- a stale
allow-list entry fails too. DIVERGENCES is empty today; the listen/endpoints
fix is a separate change and must add its own entry, which this test forces.

The reference is a vendored copy of upstream's two json5 files, byte-identical
across all five rmw_zenoh distro branches. Where AMENT_PREFIX_PATH names an
installed rmw_zenoh_cpp, the same test reads that instead, so the ROS legs also
catch the vendored copy going stale. No workflow change: those legs already run
hiroz-tests after sourcing setup.bash. AMENT_PREFIX_PATH rather than
/opt/ros/$ROS_DISTRO because this workspace also builds ROS from Nix, where no
/opt/ros exists. A second test fails if rmw_zenoh_cpp is installed but was not
selected, so that fallback cannot go silent.

crates/rmw-zenoh-rs/config/DEFAULT_RMW_ZENOH_SESSION_CONFIG.json5 is deleted.
Nothing read it, and it had drifted far enough to mislead: multicast enabled,
queries_default_timeout 10000, no listen block at all.
docs/core-concepts/services.md said a call with no server "times out after
queries_default_timeout (default: 10 min)", and advised lowering that setting
for faster failure detection. Neither is true of a ZClient.

create_client hard-codes querier_timeout to Duration::from_secs(10)
(node.rs), and ZClientBuilder::build passes it to .timeout() on the zenoh
querier (service.rs), which takes precedence over the session default. That is
the only construction site, and with_querier_timeout is pub(crate) -- so 10s
is the effective figure and no public API changes it. The one caller of
with_querier_timeout is the action client, which sets Duration::MAX and so has
no deadline at all.

Corrects the sequence diagram, its accDescr, the flashcard, the settings-table
row and the "Reduce Service Call Timeout" section, which is renamed because it
does not reduce a service call timeout. Each now says what the setting does
reach and what it does not.

Per .claude/rules/docs-consistency.md a promise the code does not keep is a
defect, so this ships with the realignment rather than after it. Making the
10s figure configurable is a feature and is not in this change.
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://ZettaScaleLabs.github.io/hiroz/pr-preview/pr-329/

Built to branch gh-pages at 2026-08-25 18:45 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

The file is not unread. crates/rmw-zenoh-rs/CMakeLists.txt installs it:

    install(
      DIRECTORY config
      DESTINATION share/${PROJECT_NAME}
    )

so deleting it made ament_cmake_symlink_install_directory fail with "can't
find .../crates/rmw-zenoh-rs/config" and took the rmw_zenoh_rs package down.

The check that missed it searched *.rs, *.toml, *.nu, *.sh and *.yml for the
file name. CMakeLists.txt was outside that list, and the reference is to the
DIRECTORY -- so no search for the file name would have found it at any breadth.
An empty search result is not evidence of no consumer.

The staleness that prompted the deletion is real and is left in place: the
installed copy still says multicast enabled and queries_default_timeout 10000,
where session_overrides() applies neither. Regenerating it from config.rs is
the fix, and it is a different change from this one.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Aligns hiroz’s Zenoh overrides with rmw_zenoh_cpp and adds regression coverage for future configuration drift.

Changes:

  • Raises the session query timeout to 10 minutes.
  • Adds vendored upstream configurations and alignment tests.
  • Corrects service-timeout documentation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/user-guide/config-advanced.md Clarifies raw-session query timeouts.
docs/core-concepts/services.md Documents client timeout behavior.
crates/hiroz/src/config.rs Sets the session query timeout to 600000 ms.
crates/hiroz-tests/tests/data/rmw_zenoh_cpp/DEFAULT_RMW_ZENOH_SESSION_CONFIG.json5 Vendors upstream session configuration.
crates/hiroz-tests/tests/data/rmw_zenoh_cpp/DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5 Vendors upstream router configuration.
crates/hiroz-tests/tests/config_upstream_alignment.rs Tests override alignment and documented divergences.
crates/hiroz-tests/Cargo.toml Adds JSON5 parsing support.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/hiroz-tests/tests/config_upstream_alignment.rs
Comment thread docs/user-guide/config-advanced.md Outdated
Comment thread docs/core-concepts/services.md Outdated
… claims

Three findings from review, each verified against source before the fix.

A DIVERGENCES entry with a blank reason exempted drift while explaining
nothing, because divergence_reason used is_some(). The reason is what makes an
entry a decision rather than an exemption, so an entry without one no longer
counts. A named check reports it, instead of the misleading "now agree on it".

The settings table gave the router a 10-minute query timeout. hiroz sets
queries_default_timeout only in session_specific_overrides, so the router keeps
zenoh's 10 seconds and diverges from rmw_zenoh_cpp, which sets 10 minutes on
both. The table now says 10 s, and the note below it states the divergence
rather than claiming the configs match exactly.

The services page said action clients set no deadline. Only the result client
does: action/client.rs applies Duration::MAX to that builder alone, and the
goal and cancel clients keep the 10-second default. Submitting and cancelling
a goal both time out.

The router divergence also exposes a limit of the test, now stated in its
module doc: it compares the keys hiroz overrides, so a key upstream sets and
hiroz leaves at zenoh's default is invisible to it.

The module doc drops its branch-history narration and follows the STE sentence
rules, as do the remaining comments.
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