VLink  2.0.0
A high-performance communication middleware
qos.h
浏览该文件的文档.
1 /*
2  * Copyright (C) 2026 by Thun Lu. All rights reserved.
3  * Author: Thun Lu <thun.lu@zohomail.cn>
4  * Repo: https://github.com/thun-res/vlink
5  * _ __ __ _ __
6  * | | / / / / (_) ____ / /__
7  * | | / / / / / / / __ \ / //_/
8  * | |/ / / /___ / / / / / / / ,<
9  * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 /**
25  * @file qos.h
26  * @brief Quality of Service (QoS) policy aggregate for VLink publishers and subscribers.
27  *
28  * @details
29  * @c Qos is a plain-old-data struct that bundles all DDS-compatible Quality of Service
30  * parameters into a single aggregate. It is passed to publishers, subscribers, clients,
31  * servers, getters, and setters to control transport behaviour.
32  *
33  * The struct mirrors DDS QoS concepts and maps cleanly onto FastDDS, CycloneDDS, and
34  * RTI DDS backends. For non-DDS backends (shm, zenoh, intra, etc.), each backend
35  * interprets the relevant subset of fields.
36  *
37  * Pre-built profiles are available in the @c QosProfile namespace (see @c qos_profile.h).
38  *
39  * | Sub-policy | Key parameter | Default |
40  * | ------------------- | ----------------------------------- | ---------------------------------- |
41  * | @c Reliability | @c kind, block_time, heartbeat_time | Reliable, 100 ms block, 3000 ms hb |
42  * | @c History | @c kind, depth | KeepLast, depth=1 |
43  * | @c Durability | @c kind | Volatile |
44  * | @c PublishMode | @c kind | Sync |
45  * | @c Liveliness | @c kind, duration | Automatic, infinite |
46  * | @c DestinationOrder | @c kind | ReceptionTimestamp |
47  * | @c Ownership | @c kind | Shared |
48  * | @c Deadline | @c period | -1 (no deadline) |
49  * | @c Lifespan | @c duration | -1 (infinite) |
50  * | @c LatencyBudget | @c duration | 0 (best-effort) |
51  * | @c ResourceLimits | max_samples / instances | 6000 / 10 / 500 |
52  * | @c Additions | @c priority, @c is_express | Normal, not express |
53  *
54  * @par Example
55  * @code
56  * // Custom QoS: best-effort, keep last 10, volatile
57  * vlink::Qos qos;
58  * qos.reliability.kind = vlink::Qos::Reliability::kBestEffort;
59  * qos.history.kind = vlink::Qos::History::kKeepLast;
60  * qos.history.depth = 10;
61  * qos.durability.kind = vlink::Qos::Durability::kVolatile;
62  *
63  * vlink::DdsConf::register_qos("my_qos", qos);
64  * auto pub = vlink::Publisher<MyMsg>::create_unique("dds://my_topic?qos=my_qos");
65  * @endcode
66  */
67 
68 #pragma once
69 
70 #include <cstdint>
71 
72 namespace vlink {
73 
74 /**
75  * @struct Qos
76  * @brief Aggregate Quality of Service policy for a VLink communication endpoint.
77  *
78  * @details
79  * All sub-policies have sensible defaults. Only the fields relevant to the active
80  * transport backend are used; unsupported fields are silently ignored.
81  *
82  * The @c name field (max 19 chars) identifies the profile for display purposes.
83  * The @c valid flag must be @c true for the Qos to be applied; @c QosProfile
84  * constants already set @c valid = @c true.
85  */
86 struct Qos final {
87  /**
88  * @struct Reliability
89  * @brief Controls whether message delivery is guaranteed.
90  *
91  * | Kind | Behaviour |
92  * | ------------ | ------------------------------------------------------ |
93  * | kBestEffort | No retransmission; messages may be lost |
94  * | kReliable | Retransmit until ACK or @c block_time expires |
95  */
96  struct Reliability final {
97  enum Kind : uint8_t {
98  kBestEffort = 0, ///< Fire-and-forget; no retransmission.
99  kReliable = 1, ///< Retransmit until acknowledged.
100  };
101 
102  Kind kind{kReliable}; ///< Delivery guarantee kind.
103  int32_t block_time{100}; ///< Max time (ms) a reliable write may block waiting for space.
104  int32_t heartbeat_time{3000}; ///< Heartbeat interval (ms) for reliable delivery.
105  };
106 
107  /**
108  * @struct History
109  * @brief Controls how many samples are kept for late-joining subscribers.
110  *
111  * | Kind | Behaviour |
112  * | ---------- | -------------------------------------------------------- |
113  * | kKeepLast | Keep the @c depth most recent samples per instance |
114  * | kKeepAll | Keep all samples (subject to ResourceLimits) |
115  */
116  struct History final {
117  enum Kind : uint8_t {
118  kKeepLast = 0, ///< Keep only the @c depth most recent samples.
119  kKeepAll = 1, ///< Keep all unread samples.
120  };
121 
122  Kind kind{kKeepLast}; ///< History retention kind.
123  int32_t depth{1}; ///< Number of samples to keep per instance (KeepLast only).
124  };
125 
126  /**
127  * @struct Durability
128  * @brief Controls how samples persist after they are published.
129  *
130  * | Kind | Behaviour |
131  * | --------------- | ------------------------------------------------------- |
132  * | kVolatile | No persistence; late joiners see only new samples |
133  * | kTransientLocal | Samples cached in the DataWriter; late joiners catch up |
134  * | kTransient | Samples persist in an external service |
135  * | kPersistent | Samples persist to stable storage |
136  */
137  struct Durability final {
138  enum Kind : uint8_t {
139  kVolatile = 0, ///< No persistence beyond the DataWriter lifetime.
140  kTransientLocal = 1, ///< DataWriter caches samples for late-joining readers.
141  kTransient = 2, ///< Durability service stores samples.
142  kPersistent = 3, ///< Samples written to stable storage.
143  };
144 
145  Kind kind{kVolatile}; ///< Durability kind.
146  };
147 
148  /**
149  * @struct PublishMode
150  * @brief Controls whether the DataWriter sends synchronously or asynchronously.
151  *
152  * | Kind | Behaviour |
153  * | ------ | ------------------------------------------------------------- |
154  * | kSync | Write completes before returning to the caller |
155  * | kASync | Write is queued and sent by a background thread |
156  */
157  struct PublishMode final {
158  enum Kind : uint8_t {
159  kSync = 0, ///< Synchronous publish.
160  kASync = 1, ///< Asynchronous publish via background thread.
161  };
162 
163  Kind kind{kSync}; ///< Publish mode.
164  };
165 
166  /**
167  * @struct Liveliness
168  * @brief Controls how the liveness of a DataWriter is asserted and detected.
169  *
170  * | Kind | Behaviour |
171  * | ------------------- | ------------------------------------------------- |
172  * | kAutomatic | Middleware asserts liveliness automatically |
173  * | kManualParticipant | Application must assert at participant level |
174  * | kManualTopic | Application must assert at topic level |
175  */
176  struct Liveliness final {
177  enum Kind : uint8_t {
178  kAutomatic = 0, ///< Automatic liveliness assertion.
179  kManualParticipant = 1, ///< Manual assertion at DomainParticipant level.
180  kManualTopic = 2, ///< Manual assertion at DataWriter level.
181  };
182 
183  Kind kind{kAutomatic}; ///< Liveliness assertion kind.
184  int32_t duration{-1}; ///< Lease duration in ms. -1 = infinite.
185  };
186 
187  /**
188  * @struct DestinationOrder
189  * @brief Controls the ordering of received samples.
190  *
191  * | Kind | Behaviour |
192  * | -------------------- | ----------------------------------------------- |
193  * | kReceptionTimestamp | Order by time the reader received the sample |
194  * | kSourceTimestamp | Order by time the writer sent the sample |
195  */
196  struct DestinationOrder final {
197  enum Kind : uint8_t {
198  kReceptionTimestamp = 0, ///< Order by reception time.
199  kSourceTimestamp = 1, ///< Order by source write time.
200  };
201 
202  Kind kind{kReceptionTimestamp}; ///< Sample ordering criterion.
203  };
204 
205  /**
206  * @struct Ownership
207  * @brief Controls whether multiple writers can write to the same instance.
208  *
209  * | Kind | Behaviour |
210  * | ---------- | --------------------------------------------------------- |
211  * | kShared | Multiple writers may update the same instance |
212  * | kExclusive | Only the writer with the highest strength may update |
213  */
214  struct Ownership final {
215  enum Kind : uint8_t {
216  kShared = 0, ///< Multiple writers share ownership.
217  kExclusive = 1, ///< Only the highest-strength writer has ownership.
218  };
219 
220  Kind kind{kShared}; ///< Ownership kind.
221  };
222 
223  /**
224  * @struct Deadline
225  * @brief Specifies the maximum period between successive data publications.
226  *
227  * @details
228  * A @c period of -1 means no deadline constraint. When the deadline is
229  * missed, the middleware fires a deadline-missed status event.
230  */
231  struct Deadline final {
232  int32_t period{-1}; ///< Max interval between writes (ms). -1 = no constraint.
233  };
234 
235  /**
236  * @struct Lifespan
237  * @brief Specifies the maximum age of a sample before it is discarded.
238  *
239  * @details
240  * A @c duration of -1 means samples never expire.
241  */
242  struct Lifespan final {
243  int32_t duration{-1}; ///< Sample maximum age (ms). -1 = infinite.
244  };
245 
246  /**
247  * @struct LatencyBudget
248  * @brief Provides a hint about the maximum acceptable end-to-end latency.
249  *
250  * @details
251  * A @c duration of 0 requests the lowest possible latency. The middleware
252  * may use this hint to schedule delivery.
253  */
254  struct LatencyBudget final {
255  int32_t duration{0}; ///< Acceptable delivery latency (ms). 0 = best possible.
256  };
257 
258  /**
259  * @struct ResourceLimits
260  * @brief Limits on the number of samples, instances, and samples per instance.
261  *
262  * @details
263  * These limits apply to the DataWriter and DataReader internal queues.
264  * Setting them too low may cause samples to be rejected under load.
265  */
266  struct ResourceLimits final {
267  int32_t max_samples{6000}; ///< Maximum total samples across all instances.
268  int32_t max_instances{10}; ///< Maximum number of instances.
269  int32_t max_samples_per_instance{500}; ///< Maximum samples per instance.
270  };
271 
272  /**
273  * @struct Additions
274  * @brief VLink-specific extensions beyond standard DDS QoS.
275  *
276  * @details
277  * @c priority controls the task dispatch priority for priority-type message loops.
278  * @c is_express hints that messages should bypass the normal queue and be sent immediately.
279  */
280  struct Additions final {
281  /**
282  * @brief Dispatch priority values for priority-aware loops.
283  *
284  * | Priority | Value | Use case |
285  * | ------------------ | ----- | ----------------------------- |
286  * | kPriorityRealTime | 1 | Hard real-time control |
287  * | kPriorityHigh | 2 | High-priority events |
288  * | kPriorityNormal | 4 | Standard application messages |
289  * | kPriorityLow | 6 | Background telemetry |
290  * | kPriorityBackground| 7 | Best-effort background tasks |
291  */
292  enum Priority : uint8_t {
293  kPriorityRealTime = 1, ///< Highest priority; hard real-time.
294  kPriorityHigh = 2, ///< High-priority processing.
295  kPriorityNormal = 4, ///< Default application priority.
296  kPriorityLow = 6, ///< Low-priority background work.
297  kPriorityBackground = 7, ///< Lowest priority; background tasks.
298  };
299 
300  Priority priority{kPriorityNormal}; ///< Task dispatch priority.
301  bool is_express{false}; ///< If true, bypass normal queuing for immediate delivery.
302  };
303 
304  char name[20] = {0}; ///< Profile name (max 19 chars + NUL). For display only.
305  bool valid{false}; ///< Must be true for the Qos to be applied by the transport.
306  Reliability reliability; ///< Delivery guarantee policy.
307  History history; ///< Sample retention policy.
308  Durability durability; ///< Sample persistence policy.
309  PublishMode publish_mode; ///< Synchronous or asynchronous publishing.
310  Liveliness liveliness; ///< Liveliness assertion policy.
311  DestinationOrder destination_order; ///< Sample ordering policy.
312  Ownership ownership; ///< Writer ownership policy.
313  Deadline deadline; ///< Maximum period between publications.
314  Lifespan lifespan; ///< Maximum sample age before discard.
315  LatencyBudget latency_budget; ///< Acceptable end-to-end latency hint.
316  ResourceLimits resource_limits; ///< Internal queue size limits.
317  Additions additions; ///< VLink-specific extensions.
318 };
319 
320 } // namespace vlink