Skip to main content

Deadline QoS Policy

The Deadline policy specifies the maximum time between data updates.

Purpose

Deadline monitors data freshness:

  • Writers commit to publishing within the deadline period
  • Readers expect samples within the deadline period
  • Violations trigger callbacks for handling

Configuration

use hdds::prelude::*;
use std::time::Duration;

// Writer commits to 100ms update rate
let writer_qos = DataWriterQos::default()
.deadline(Deadline::new(Duration::from_millis(100)));

// Reader expects updates within 100ms
let reader_qos = DataReaderQos::default()
.deadline(Deadline::new(Duration::from_millis(100)));

Default Value

Default is infinite (no deadline monitoring):

let qos = DataWriterQos::default();
// deadline = Duration::MAX (infinite)

Compatibility Rules

Writer deadline must be less than or equal to Reader deadline (writer must be faster):

WriterReaderMatch?
100 ms200 ms✅ Yes
100 ms100 ms✅ Yes
200 ms100 ms❌ No
Infinite100 ms❌ No
100 msInfinite✅ Yes

Rule: Writer.deadline ≤ Reader.deadline

Deadline Tracking

Writer Side

The writer tracks time since last write() call:

let writer = publisher.create_writer_with_qos(&topic, writer_qos)?;

// Start deadline timer
writer.write(&sample)?;

// If no write within 100ms → deadline missed

Reader Side

The reader tracks time since last sample received per instance:

let reader = subscriber.create_reader_with_qos(&topic, reader_qos)?;

// Deadline timer starts when first sample received
// If no new sample within 100ms → deadline missed

Handling Violations

Listener Callbacks

use hdds::prelude::*;

struct MyListener;

impl DataWriterListener for MyListener {
fn on_offered_deadline_missed(
&mut self,
writer: &DataWriter<SensorData>,
status: OfferedDeadlineMissedStatus,
) {
eprintln!(
"Writer missed deadline! Total: {}, Change: {}",
status.total_count,
status.total_count_change
);
}
}

impl DataReaderListener for MyListener {
fn on_requested_deadline_missed(
&mut self,
reader: &DataReader<SensorData>,
status: RequestedDeadlineMissedStatus,
) {
eprintln!(
"Reader deadline missed for instance {:?}",
status.last_instance_handle
);
}
}

Status Polling

// Check deadline status manually
let status = writer.get_offered_deadline_missed_status()?;
if status.total_count_change > 0 {
println!("Missed {} deadlines", status.total_count_change);
}

Per-Instance Deadline

For keyed topics, deadline is tracked per instance:

// Topic: SensorReading with @key sensor_id

let reader_qos = DataReaderQos::default()
.deadline(Deadline::new(Duration::from_millis(500)));

// Each sensor_id has its own deadline timer:
// sensor_1: last_update=T1, deadline at T1+500ms
// sensor_2: last_update=T2, deadline at T2+500ms

Use Cases

Periodic Sensor Data

// Sensor publishes at 10 Hz, reader expects updates
let deadline = Duration::from_millis(100); // 10 Hz

let writer_qos = DataWriterQos::default()
.deadline(Deadline::new(deadline))
.reliability(Reliability::BestEffort);

let reader_qos = DataReaderQos::default()
.deadline(Deadline::new(deadline * 2)) // 200ms tolerance
.reliability(Reliability::BestEffort);

Heartbeat Monitoring

// Monitor node liveness with heartbeats
let heartbeat_period = Duration::from_secs(1);
let tolerance = Duration::from_secs(3);

let writer_qos = DataWriterQos::default()
.deadline(Deadline::new(heartbeat_period));

let reader_qos = DataReaderQos::default()
.deadline(Deadline::new(tolerance));

Control Loop

// Real-time control at 1 kHz
let control_period = Duration::from_micros(1000); // 1 ms

let writer_qos = DataWriterQos::default()
.deadline(Deadline::new(control_period))
.reliability(Reliability::BestEffort)
.history(History::KeepLast { depth: 1 });

Best Practices

  1. Set reader deadline >= writer deadline
  2. Add tolerance for network jitter (2-3× expected period)
  3. Use listeners for real-time alerting
  4. Monitor deadline statistics in production
// Good: Reader has tolerance
let writer_deadline = Duration::from_millis(100);
let reader_deadline = Duration::from_millis(150); // 50% tolerance

// Bad: Reader too strict
let writer_deadline = Duration::from_millis(100);
let reader_deadline = Duration::from_millis(100); // No tolerance!

Interaction with Other Policies

Deadline + Liveliness

Both monitor entity health, but differently:

PolicyMonitorsGranularity
DeadlineData updatesPer instance
LivelinessWriter existencePer writer
// Combined monitoring
let qos = DataWriterQos::default()
.deadline(Deadline::new(Duration::from_millis(100))) // Data rate
.liveliness(Liveliness::ManualByTopic {
lease_duration: Duration::from_secs(10), // Writer alive
});

Deadline + Reliability

DeadlineReliabilityBehavior
SetBestEffortDeadline may miss on network loss
SetReliableRetransmissions help meet deadline

Performance Notes

  • Deadline checking adds minimal CPU overhead (~1 μs per sample)
  • Per-instance tracking requires memory per active instance
  • High-frequency deadlines (< 1ms) require careful tuning

Next Steps