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'usage | Exigences |
|---|---|
| Streaming de capteurs | Debit eleve, quelques pertes acceptables |
| Commandes | Livraison garantie, ordonnees |
| Synchro d'etat | Les retardataires recoivent l'etat courant |
| Controle temps reel | Basse 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
| Politique | Fonction |
|---|---|
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
- Reliability - Guide detaille sur la fiabilite
- Durability - Donnees historiques
- Deadline - Exigences de timing
- Memento QoS - Reference rapide