pub struct RuntimeConfig {Show 27 fields
pub tick_period: Duration,
pub spdp_period: Duration,
pub initial_announce_count: u32,
pub initial_announce_period: Duration,
pub spdp_multicast_group: Ipv4Addr,
pub multicast_interface: Ipv4Addr,
pub spdp_multicast_send: bool,
pub discovery_server: bool,
pub max_reassembly_sample_bytes: usize,
pub initial_peers: Vec<Locator>,
pub user_transport: Option<UserTransportKind>,
pub user_transports: Vec<UserTransportKind>,
pub announce_secure_endpoints: bool,
pub enable_secure_spdp: bool,
pub wlp_period: Duration,
pub participant_lease_duration: Duration,
pub user_data: Vec<u8>,
pub observability: SharedSink,
pub recv_thread_priority: Option<i32>,
pub tick_thread_priority: Option<i32>,
pub recv_thread_cpus: Option<Vec<usize>>,
pub tick_thread_cpus: Option<Vec<usize>>,
pub extra_recv_threads: usize,
pub data_representation_offer: Vec<i16>,
pub data_rep_match_mode: DataRepMatchMode,
pub external_tick: bool,
pub scheduler_tick: bool,
}Expand description
Configuration for the runtime. Exposed via DomainParticipant factory methods.
Fields§
§tick_period: DurationTick period of the event loop. Default 50 ms.
spdp_period: DurationSPDP announce period. Default 5 s.
initial_announce_count: u32C3 WiFi-robust discovery — number of initial SPDP announces sent at the
fast Self::initial_announce_period cadence (instead of spdp_period)
while no peer is yet discovered. Default
DEFAULT_INITIAL_ANNOUNCE_COUNT. 0 disables the burst (legacy
single-announce-then-spdp_period behaviour).
initial_announce_period: DurationPeriod between initial-announcement-burst SPDP sends. Default
DEFAULT_INITIAL_ANNOUNCE_PERIOD.
spdp_multicast_group: Ipv4AddrSPDP multicast group (IPv4). Default 239.255.0.1 (Spec §9.6.1.4.1).
multicast_interface: Ipv4AddrInterface address for the multicast join. Default 0.0.0.0 (the kernel picks the default interface).
spdp_multicast_send: boolC1: whether SPDP beacons are sent via multicast. Default true
(spec behavior). false (env ZERODDS_NO_MULTICAST) → pure
unicast discovery via Self::initial_peers, not a single
multicast packet — for networks that drop multicast (WiFi/cloud
VPC), and for a rigorous multicast-free discovery proof.
discovery_server: boolA1: discovery-server mode. When true, this participant relays the
raw SPDP (participant-locator) announcements between the clients that
point their Self::initial_peers at it — so N clients discover each
other through one well-known address instead of an O(N²) peer list or
multicast. Crucially it relays only SPDP (participant discovery);
SEDP (endpoint discovery, incl. dynamically-created ROS-2 Action
endpoints) then happens directly peer-to-peer between the real
participants — which is exactly why ROS-2 Actions work over it, unlike a
SEDP-proxying discovery server. Default false. Plain discovery only
(DDS-Security secured discovery-server relay is a follow-up).
max_reassembly_sample_bytes: usizeC3: max reassemblable sample size (DoS cap of the fragment
assembler). Larger samples are silently discarded. The rtps
default was 1 MiB (the phase-1 assumption “large images = no
use case”) — too small for ROS PointCloud2/Image (often several
MB). Default here 16 MiB; env ZERODDS_MAX_SAMPLE_BYTES (bytes)
overrides. Still a deliberate DoS guard, just ROS-realistic.
initial_peers: Vec<Locator>C1 multicast-free discovery: unicast initial-peer locators to
which SPDP beacons are sent in addition to multicast. Default
empty (= pure multicast behavior as before). Populated via
RuntimeConfig::default from the env ZERODDS_PEERS (comma
list of ip or ip:port). An ip without a port is expanded to
the well-known SPDP unicast ports of participant indices 0..N
(see [expand_initial_peer]).
user_transport: Option<UserTransportKind>Transport for DCPS user traffic. None (default) → fall back to
the env var ZERODDS_USER_TRANSPORT, otherwise UDPv4. Discovery
(SPDP/SEDP) remains UDPv4 multicast independently of this. Ignored when
Self::user_transports is non-empty.
user_transports: Vec<UserTransportKind>Preference-ordered set of transports for DCPS user traffic. When
non-empty, the runtime builds a LayeredUserTransport
over all of them: each datagram is routed to the first transport whose
locator kind matches the destination (so list the fast/local transport
first — e.g. [Shm, UdpV4] — and the fallback last), and receives are
multiplexed from all of them. Empty (default) → single-transport via
Self::user_transport.
announce_secure_endpoints: booltrue → the SPDP beacon additionally announces the 12 secure
discovery bits (16..27, DDS-Security 1.2 §7.4.7.1). Default
false — only standard bits are announced. Set by the DCPS
factory once a PolicyEngine is configured. This flag is available
even without the security feature, so that tests can check bit
presence without activating the whole crypto crate.
enable_secure_spdp: boolFastDDS interop: run the reliable secure SPDP channel (0xff0101c2/c7,
ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_*). FastDDS announces
its full secured participant data (identity_token/security_info) over
this channel and gates the crypto-token reciprocation/endpoint matching
on it; cyclone does NOT need it (cyclone↔zerodds runs without). Default off
— enable only for FastDDS cross-vendor.
wlp_period: DurationWLP-Tick-Periode (Writer-Liveliness-Protocol, RTPS 2.5 §8.4.13).
Duration::ZERO → default participant_lease_duration / 3
(spec recommendation: three misses before the reader marks the
writer as not-alive). A direct override enables aggressive
tests.
participant_lease_duration: DurationLease duration announced in the SPDP beacon as
PARTICIPANT_LEASE_DURATION (spec default 100 s). Also used as the
basis for the AUTOMATIC WLP tick (wlp_period = participant_lease_duration / 3 if wlp_period == Duration::ZERO).
user_data: Vec<u8>USER_DATA bytes of the participant (DDS 1.4 §2.2.3.1
UserDataQosPolicy). Announced in the SPDP beacon as PID_USER_DATA
(DDSI-RTPS §9.6.3.2) and exposed on the receiver side in
ParticipantBuiltinTopicData.user_data. Default empty.
observability: SharedSinkObservability sink. Default is null_sink() — each event emit is
then a direct return without allocation on the consumer side.
Consumers inject e.g.
zerodds_foundation::observability::StderrJsonSink (JSON lines
for Vector/fluentd/Datadog) or their own OTLP bridge.
recv_thread_priority: Option<i32>Sprint D.5d lever C — RT pinning + priority. Linux-only; on macOS/Windows the hooks are no-ops.
SCHED_FIFO priority (1-99) for the three recv workers (SPDP MC,
metatraffic, user data). None = default scheduler (CFS).
Some(80) is the spec recommendation for real-time paths. Requires
CAP_SYS_NICE or an RLIMIT_RTPRIO-permitted user.
tick_thread_priority: Option<i32>Like Self::recv_thread_priority, but for the tick worker.
recv_thread_cpus: Option<Vec<usize>>CPU affinity mask for the recv workers. None = no affinity (the
kernel schedules freely). A list of CPU indices, e.g.
vec![2, 3] for cores 2+3. Set via sched_setaffinity; all three
recv threads share the same mask.
tick_thread_cpus: Option<Vec<usize>>Like Self::recv_thread_cpus, but for the tick worker.
extra_recv_threads: usizeOpt-3 (Spec zerodds-zero-copy-1.0 §9): number of additional
user-data recv workers that listen on the same port as
user_unicast via SO_REUSEPORT. 0 (default) = only the primary
recv_user_data_loop worker. Under high recv load the pool scales
linearly with cores (kernel flow hashing distributes incoming
datagrams). Recommended values: 1-3 additional workers per CPU
core.
data_representation_offer: Vec<i16>D.5g — default DataRepresentation list announced in SEDP PublicationData and SEDP SubscriptionData, when not overridden per-writer/reader (UserWriterConfig/UserReaderConfig).
Important: per strict spec (XTypes 1.3 §7.6.3.1.2) the first
element is the writer’s “offered” and must be in the reader’s
“accepted” list for a match to happen. Default [XCDR1, XCDR2] =
legacy-first → max interop with the RTI Connext Shapes Demo
(XCDR1-only). Pure-XCDR2 deployments can switch this to [XCDR2]
or [XCDR2, XCDR1] for bandwidth efficiency and
@appendable/@mutable support.
Empty (vec![]) is interpreted per spec as [XCDR1].
data_rep_match_mode: DataRepMatchModeD.5g — default match mode for DataRepresentation negotiation.
Strict (XTypes 1.3 §7.6.3.1.2 normative): writer.first ∈
reader.list = match. Tolerant (industry norm): any overlap =
match, picks the first overlap as the wire format.
Default Tolerant because Cyclone DDS and FastDDS match this way —
maximizes interop. The strict setting is only meaningful for
formal spec-compliance tests.
external_tick: boolzerodds-async-1.0 §4 — when true, start() does not spawn the
dedicated zdds-tick std::thread. The periodic tick (SPDP announce,
SEDP/WLP, deadline/lifespan/liveliness) must then be driven externally
via DcpsRuntime::tick_driver. Used by the async API’s
spawn_in_tokio, which multiplexes many participants’ tick loops onto
a tokio runtime instead of one thread each. Default false (internal
thread, unchanged behaviour). The recv worker threads are unaffected —
they block on socket recv and stay regardless.
scheduler_tick: boolD.5e Phase 3 — when true, start() drives the periodic tick via the
event-driven deadline scheduler (crate::scheduler) instead of the
fixed-tick_period poll: the worker parks until the next due deadline
(SPDP announce, or a fine floor while user endpoints/QoS timers are
active) or until a write/recv raise wakes it — no busy-poll, lower idle
CPU, lower tail latency. The work done per wake is the unchanged
run_tick_iteration (identical wire output + cadence — cross-vendor
safe). Default true since D.5e Phase C (2026-06-14) — set
ZERODDS_SCHEDULER_TICK=0 or this field to false for the classic
fixed-period tick_loop. Mutually exclusive with external_tick
(external wins).
Implementations§
Source§impl RuntimeConfig
impl RuntimeConfig
Sourcepub fn ros_defaults() -> Self
pub fn ros_defaults() -> Self
C4: robotics-capable defaults for out-of-the-box ROS-2 interop.
Saves the manual env tuning otherwise needed for real ROS-2 nodes.
Specifically, compared to RuntimeConfig::default:
data_representation_offer = [XCDR1, XCDR2]:rmw_cyclonedds/rmw_fastrtpswrite XCDR1 for final/simple types (e.g.std_msgs/String). An XCDR2-only reader does not match an XCDR1 writer — so the ROS reader here offers both legacy-first (tolerant match is already the default). This is the clean, ROS-specific variant of theZERODDS_DATA_REPR_OFFERenv workaround, WITHOUT changing the globalDEFAULT_OFFER(XCDR2-only, deliberately for FastDDS/OpenDDS XCDR2 readers).
The ROS-realistic reassembly cap (16 MiB, PointCloud2/Image) is already the global default and is carried over here.
Sourcepub fn multi_robot() -> Self
pub fn multi_robot() -> Self
C6 multi-robot / WAN / cross-subnet profile.
A named profile for fleets that span subnets, the cloud, or WiFi —
environments that drop IP multicast, so SPDP discovery cannot rely on
the multicast beacon. It is the ros_defaults
representation offer plus:
- Multicast-free discovery (
spdp_multicast_send = false): participants find each other purely through unicast initial peers, regardless of theZERODDS_NO_MULTICASTenv. Set the peers viaZERODDS_PEERS(a comma list ofiporip:port); a port-lessipis expanded to the well-known SPDP unicast ports of the first N participant indices (ZERODDS_MAX_PEER_PARTICIPANTS). - WAN-tolerant liveliness: a longer participant lease (300 s vs the 100 s spec default) so transient cross-subnet RTT spikes or brief link drops do not trigger a false liveliness loss.
Domain isolation is the caller’s lever: pass a fleet-dedicated
domain_id to DcpsRuntime::start to keep robots off the default
domain 0. The profile deliberately does not pick a domain for you.
use zerodds_dcps::runtime::RuntimeConfig;
let cfg = RuntimeConfig::multi_robot();
assert!(!cfg.spdp_multicast_send); // unicast-only discoverySourcepub fn discovery_server() -> Self
pub fn discovery_server() -> Self
A1 — discovery-server profile (the server side). Multicast-free, with
the SPDP relay on (Self::discovery_server): clients point their
initial_peers/ZERODDS_PEERS at this one well-known address and the
server bridges their participant discovery, so N clients find each other
without an O(N²) peer list or multicast. SEDP (incl. ROS-2 Action
endpoints) stays direct peer-to-peer — no SEDP proxy, no Action breakage.
Clients run with RuntimeConfig::multi_robot (or any multicast-free
config) and set ZERODDS_PEERS to the server’s address.
use zerodds_dcps::runtime::RuntimeConfig;
let server = RuntimeConfig::discovery_server();
assert!(server.discovery_server);
assert!(!server.spdp_multicast_send); // unicast-onlyTrait Implementations§
Source§impl Clone for RuntimeConfig
impl Clone for RuntimeConfig
Source§fn clone(&self) -> RuntimeConfig
fn clone(&self) -> RuntimeConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more