Skip to main content

Runtime Configuration

Centralized configuration management for HDDS with lock-free performance.

Overview

The configuration module provides:

  • Static constants - RTPS spec values (ports, IPs, timing)
  • RuntimeConfig - Dynamic key-value store (QoS, custom settings)
  • Lock-free operations - DashMap + ArcSwap for high concurrency
  • Port formula helpers - Calculate RTPS ports for any domain/participant

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│ RuntimeConfig │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ QoS Store (DashMap) │ │
│ │ "qos.reliability.kind" → "RELIABLE" │ │
│ │ "qos.durability.kind" → "TRANSIENT_LOCAL" │ │
│ │ "qos.history.depth" → "10" │ │
│ │ "user.cache_size" → "1000" │ │
│ │ "app.debug_mode" → "true" │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Port Mapping (ArcSwap) │ │
│ │ metatraffic_multicast: 7400 │ │
│ │ sedp_unicast: 7410 │ │
│ │ user_unicast: 7411 │ │
│ └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Static Constants

RTPS Port Mapping (Sec. 9.6.1.1)

use hdds::config::*;

// Base port (IANA registered: 7400-7469)
const PORT_BASE: u16 = 7400;

// Port calculation gains
const DOMAIN_ID_GAIN: u16 = 250;
const PARTICIPANT_ID_GAIN: u16 = 2;

// Offsets
const SEDP_UNICAST_OFFSET: u16 = 10;
const USER_UNICAST_OFFSET: u16 = 11;
const DATA_MULTICAST_OFFSET: u16 = 1;

Pre-calculated Ports (Domain 0, Participant 0)

ConstantValueDescription
SPDP_MULTICAST_PORT_DOMAIN07400SPDP discovery multicast
DATA_MULTICAST_PORT_DOMAIN07401User data multicast
SEDP_UNICAST_PORT_DOMAIN0_P07410SEDP unicast
USER_UNICAST_PORT_DOMAIN0_P07411User data unicast

Port Calculation Functions

use hdds::config::{spdp_multicast_port, sedp_unicast_port, user_unicast_port};

// SPDP multicast port for any domain
let port = spdp_multicast_port(0); // 7400
let port = spdp_multicast_port(1); // 7650
let port = spdp_multicast_port(2); // 7900

// SEDP unicast port for domain and participant
let port = sedp_unicast_port(0, 0); // 7410
let port = sedp_unicast_port(0, 1); // 7412
let port = sedp_unicast_port(1, 0); // 7660

// User data unicast port
let port = user_unicast_port(0, 0); // 7411
let port = user_unicast_port(0, 1); // 7413

Multicast Addresses

use hdds::config::{MULTICAST_IP, MULTICAST_GROUP};

// Standard RTPS multicast (239.255.0.1)
let ip: [u8; 4] = MULTICAST_IP; // [239, 255, 0, 1]
let group: &str = MULTICAST_GROUP; // "239.255.0.1"

// Alternative (RTI legacy)
let alt_ip = MULTICAST_IP_ALT; // [239, 255, 0, 2]

Timing Constants

ConstantValueDescription
SPDP_ANNOUNCEMENT_PERIOD_MS3000SPDP announce interval
PARTICIPANT_LEASE_DURATION_MS30000Participant timeout
LEASE_CHECK_INTERVAL_MS1000Lease check frequency

Buffer Sizes

ConstantValueDescription
RX_RING_SIZE256Discovery RX ring buffer
RX_POOL_SIZE255Zero-copy buffer pool
MTU_SIZE1500Ethernet MTU
FRAGMENT_BUFFER_SIZE256Max fragments in flight
FRAGMENT_TIMEOUT_MS500Fragment reassembly timeout
READER_HISTORY_RING_SIZE1024DataReader history

RuntimeConfig

Creating Configuration

use hdds::config::RuntimeConfig;
use std::sync::Arc;

// Create new config
let config = Arc::new(RuntimeConfig::new());

// Pass to components (cheap clone - just Arc increment)
let config_clone = config.clone();

Custom Port Mapping

Override RTPS formula with custom ports:

use hdds::transport::{PortMapping, CustomPortMapping};

let custom = CustomPortMapping {
spdp_multicast: 9400,
sedp_unicast: 9410,
user_unicast: 9411,
};

let mapping = PortMapping::from_custom(custom);
config.set_port_mapping(mapping);

// Read back
if let Some(ports) = config.get_port_mapping() {
println!("SPDP multicast: {}", ports.metatraffic_multicast);
}

// Clear (revert to RTPS formula)
config.clear_port_mapping();

User Configuration

For application-specific settings, use user.* or app.* prefixes:

// Set user-land config
config.set_user("user.cache_size", "1000");
config.set_user("app.debug_mode", "true");

// Get config
let cache_size = config.get_user_string("user.cache_size"); // Some("1000")
let debug = config.get_user("app.debug_mode"); // Some(Arc<"true">)

// Check existence
if config.contains_user("user.cache_size") {
// ...
}

// Remove
config.remove_user("user.cache_size");
Namespace Restriction

set_user() only accepts keys starting with user. or app.. Other prefixes are ignored with a log warning.

QoS Configuration

Set QoS parameters programmatically:

use hdds::config::{RuntimeConfig, qos};

let config = RuntimeConfig::new();

// Bulk set (efficient for XML loading)
config.set_qos_bulk(vec![
(qos::RELIABILITY_KIND, qos::RELIABLE),
(qos::DURABILITY_KIND, qos::TRANSIENT_LOCAL),
(qos::HISTORY_DEPTH, "10"),
]);

// Or with owned strings (dynamic)
config.set_qos_bulk_owned(vec![
("qos.reliability.kind".to_string(), "RELIABLE".to_string()),
("qos.history.depth".to_string(), "100".to_string()),
]);

QoS Keys and Values

The qos module provides type-safe constants:

use hdds::config::qos;

// Keys
qos::RELIABILITY_KIND // "qos.reliability.kind"
qos::DURABILITY_KIND // "qos.durability.kind"
qos::HISTORY_KIND // "qos.history.kind"
qos::HISTORY_DEPTH // "qos.history.depth"
qos::LIVELINESS_KIND // "qos.liveliness.kind"
qos::DEADLINE_PERIOD // "qos.deadline.period"
qos::OWNERSHIP_KIND // "qos.ownership.kind"
qos::PARTITION_NAME // "qos.partition.name"

// Values
qos::RELIABLE // "RELIABLE"
qos::BEST_EFFORT // "BEST_EFFORT"
qos::TRANSIENT_LOCAL // "TRANSIENT_LOCAL"
qos::VOLATILE // "VOLATILE"
qos::KEEP_LAST // "KEEP_LAST"
qos::KEEP_ALL // "KEEP_ALL"
qos::AUTOMATIC // "AUTOMATIC"
qos::MANUAL_BY_PARTICIPANT // "MANUAL_BY_PARTICIPANT"

Search Operations

// Search by prefix
let reliability_params = config.search_qos_prefix("qos.reliability.");
// → [("qos.reliability.kind", "RELIABLE"), ("qos.reliability.max_blocking_time", "100")]

// Search by pattern (contains)
let timeouts = config.search_qos_pattern("duration");
// → [("qos.liveliness.lease_duration", "30000"), ...]

// Get all entries
let all = config.get_all_qos();
println!("Config has {} entries", config.len());

Performance

RuntimeConfig is optimized for high-concurrency access:

OperationTimeNotes
get_port_mapping()~20 nsAtomic load
set_port_mapping()~50 nsAtomic swap
get_user()~80 nsDashMap lookup
set_user()~100 nsDashMap insert
search_qos_prefix()O(n)Full scan

Key characteristics:

  • Lock-free: DashMap uses sharding, not global locks
  • Zero-copy: Arc<str> keys/values avoid cloning
  • Thread-safe: Safe concurrent access from any thread

Integration Example

use hdds::config::{RuntimeConfig, qos};
use std::sync::Arc;

fn setup_participant() {
// Create shared config
let config = Arc::new(RuntimeConfig::new());

// Set default QoS
config.set_qos_bulk(vec![
(qos::RELIABILITY_KIND, qos::RELIABLE),
(qos::DURABILITY_KIND, qos::VOLATILE),
(qos::HISTORY_KIND, qos::KEEP_LAST),
(qos::HISTORY_DEPTH, "10"),
]);

// Application-specific settings
config.set_user("app.telemetry_enabled", "true");
config.set_user("user.max_samples", "1000");

// Pass to DDS components
// (each clone is just an Arc increment)
let participant = ParticipantBuilder::new()
.with_config(config.clone())
.build();
}

Environment Variables

Configuration can also be set via environment:

VariableDescription
HDDS_CONFIG_FILEPath to XML config file
HDDS_DISCOVERY_PORTOverride SPDP port
HDDS_MULTICAST_DISABLEDisable multicast (1/0)
HDDS_SHM_DISABLEDisable shared memory (1/0)

See Environment Variables for the complete list.