Aller au contenu principal

Vue d'ensemble de la qualite de service

Les politiques de qualite de service (QoS) controlent la facon dont DDS delivre les donnees, offrant un controle fin sur la fiabilite, le timing, l'utilisation des ressources, et bien plus.

Pourquoi les QoS ?

Differentes applications ont des besoins differents :

Cas d'usageExigences
Streaming de capteursDebit eleve, quelques pertes acceptables
CommandesLivraison garantie, ordonnees
Synchro d'etatLes retardataires recoivent l'etat courant
Controle temps reelBasse latence, suivi des deadlines

Les politiques QoS vous permettent de configurer ces comportements de maniere declarative.

Categories de politiques QoS

+---------------------------------------------------------+
| Groupes de politiques QoS |
+-----------------+-----------------+---------------------+
| Livraison | Timing | Gestion ressources |
| - Reliability | - Deadline | - History |
| - Durability | - Latency Budget| - ResourceLimits |
| - History | - Lifespan | |
+-----------------+-----------------+---------------------+
| Ownership | Ordonnancement | Cycle de vie |
| - Ownership | - DestinationOrd| - Liveliness |
| - OwnershipStr | - Presentation | - WriterDataLifecycle|
| | | - ReaderDataLifecycle|
+-----------------+-----------------+---------------------+
| Metadonnees : UserData, TopicData, GroupData, Partition |
+---------------------------------------------------------+

Politiques QoS principales

Reliability

Controle si la livraison des donnees est garantie :

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<SensorData>("sensors/data")?;

// Best effort - may lose samples (fast)
let writer = topic
.writer()
.qos(QoS::best_effort())
.build()?;

// Reliable - guaranteed delivery with retransmits
let writer = topic
.writer()
.qos(QoS::reliable())
.build()?;

Durability

Controle la persistance des donnees pour les Subscribers qui se connectent en retard :

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<SensorData>("sensors/data")?;

// Volatile - no history for late joiners (default)
let writer = topic
.writer()
.qos(QoS::reliable().volatile())
.build()?;

// Transient Local - keep samples in memory for late joiners
let writer = topic
.writer()
.qos(QoS::reliable().transient_local())
.build()?;

// Persistent - survive process restart
let writer = topic
.writer()
.qos(QoS::reliable().persistent())
.build()?;

History

Controle le nombre d'echantillons conserves :

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<SensorData>("sensors/data")?;

// Keep last N samples per instance
let writer = topic
.writer()
.qos(QoS::reliable().keep_last(10))
.build()?;

// Keep all samples
let writer = topic
.writer()
.qos(QoS::reliable().keep_all())
.build()?;

Compatibilite QoS

Les Writers et Readers doivent avoir des QoS compatibles pour communiquer :

Writer QoS          Reader QoS           Match ?
---------------------------------------------------
reliable() --> reliable() Oui
reliable() --> best_effort() Oui
best_effort() --> best_effort() Oui
best_effort() --> reliable() NON

persistent() --> persistent() Oui
persistent() --> transient_local() Oui
persistent() --> volatile() Oui
transient_local() --> transient_local() Oui
transient_local() --> volatile() Oui
transient_local() --> persistent() NON
volatile() --> volatile() Oui
volatile() --> transient_local() NON

Regle : Le Writer doit offrir au moins ce que le Reader demande.

API fluent Builder

HDDS utilise un patron fluent builder pour les QoS :

use hdds::QoS;

// Start with a preset
let qos = QoS::reliable()
.keep_last(100) // History: keep last 100 samples
.transient_local(); // Durability: cache for late joiners

// Or best effort for speed
let qos = QoS::best_effort()
.keep_last(1) // Minimal history
.volatile(); // No caching

Profils QoS courants

Streaming de capteurs

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("sensor_stream")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<SensorData>("sensors/imu")?;

// Fast, may lose samples
let writer = topic
.writer()
.qos(QoS::best_effort().keep_last(1))
.build()?;

Synchronisation d'etat

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("state_sync")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<StateData>("system/state")?;

// Reliable with caching for late joiners
let writer = topic
.writer()
.qos(QoS::reliable().keep_last(1).transient_local())
.build()?;

File de commandes

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("command_queue")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<Command>("robot/commands")?;

// Every command must be delivered
let writer = topic
.writer()
.qos(QoS::reliable().keep_all())
.build()?;

Journal d'evenements

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("event_log")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<AuditEvent>("audit/events")?;

// Persistent event log survives restarts
let writer = topic
.writer()
.qos(QoS::reliable().keep_all().persistent())
.build()?;

Politiques de timing

Deadline

Surveiller la fraicheur des donnees :

use hdds::{Participant, QoS, TransportMode};
use std::time::Duration;

let participant = Participant::builder("deadline_example")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<SensorData>("sensors/data")?;

// Writer must publish within 100ms
let writer = topic
.writer()
.qos(QoS::reliable().deadline(Duration::from_millis(100)))
.build()?;

Liveliness

Detecter les defaillances de Writer :

use hdds::{Participant, QoS, TransportMode};
use std::time::Duration;

let participant = Participant::builder("liveliness_example")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

let topic = participant.topic::<Heartbeat>("system/heartbeat")?;

// Writer automatically asserts liveliness
// Reader notified if writer stops for 10s
let writer = topic
.writer()
.qos(QoS::reliable().liveliness_automatic(Duration::from_secs(10)))
.build()?;

Resume des politiques QoS

PolitiqueFonction
reliable() / best_effort()Garantie de livraison
transient_local() / volatile() / persistent()Donnees historiques
keep_last(n) / keep_all()Buffer d'echantillons
deadline()Suivi du taux de mise a jour
liveliness_*()Detection de defaillance

Depannage QoS

Pas d'appariement (QoS incompatibles)

Warning: Writer and Reader QoS incompatible

Verifiez :

  • Reliability : Writer >= Reader
  • Durability : Writer >= Reader
  • Deadline : Writer <= Reader
  • Liveliness : Writer kind >= Reader kind

Deadlines manquees

Warning: Deadline missed

Solutions :

  • Augmenter la periode de deadline
  • Reduire le taux de publication
  • Verifier les problemes reseau

Prochaines etapes