VLink  2.0.0
A high-performance communication middleware
status_detail.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 status_detail.h
26  * @brief Concrete @c Status event structs carrying DDS-style counters, handles, and reason codes.
27  *
28  * @details
29  * Each struct here implements one entry in @c Status::Type and exposes the precise fields the
30  * matching DDS event provides. Counter fields cover lifetime totals and per-notification deltas
31  * so user code can decide whether to react. Handles point at the most recently affected peer
32  * or instance and follow the opaque @c InstanceHandle protocol described in @c status.h.
33  *
34  * @par Detail fields by event
35  *
36  * | Event | Counter fields | Handle / reason field |
37  * | --------------------------- | --------------------------------------------- | ------------------------------- |
38  * | @c PublicationMatched | total / current count + deltas | @c last_subscription_handle |
39  * | @c OfferedDeadlineMissed | @c total_count, @c total_count_change | @c last_instance_handle |
40  * | @c OfferedIncompatibleQos | @c total_count, @c total_count_change | @c last_policy_id |
41  * | @c LivelinessLost | @c total_count, @c total_count_change | - |
42  * | @c SubscriptionMatched | total / current count + deltas | @c last_publication_handle |
43  * | @c RequestedDeadlineMissed | @c total_count, @c total_count_change | @c last_instance_handle |
44  * | @c LivelinessChanged | alive / not-alive count + deltas | @c last_publication_handle |
45  * | @c SampleRejected | @c total_count, @c total_count_change | @c last_reason + handle |
46  * | @c RequestedIncompatibleQos | @c total_count, @c total_count_change | @c last_policy_id |
47  * | @c SampleLost | @c total_count, @c total_count_change | - |
48  *
49  * @par Example
50  * @code
51  * sub->register_status_callback([](vlink::Status::BasePtr status) {
52  * if (status->get_type() == vlink::Status::kSampleRejected) {
53  * auto detail = status->as<vlink::Status::SampleRejected>();
54  * if (detail->last_reason == vlink::Status::SampleRejected::kRejectedBySamplesLimit) {
55  * VLOG_W("rejected: queue full, total=", detail->total_count);
56  * }
57  * }
58  * });
59  * @endcode
60  */
61 
62 #pragma once
63 
64 #include <cstdint>
65 #include <string>
66 
67 #include "./status.h"
68 
69 namespace vlink {
70 
71 namespace Status {
72 
73 /* ================== For writer ================== */
74 
75 /**
76  * @struct PublicationMatched
77  * @brief Writer-side event raised when a matching subscriber appears or disappears.
78  *
79  * @details
80  * Provides cumulative and current counts of matched subscribers together with the most recent
81  * subscription handle. Negative @c current_count_change indicates a peer was removed.
82  */
83 struct VLINK_EXPORT PublicationMatched final : public Base {
84  public:
85  /**
86  * @brief Returns @c kPublicationMatched.
87  *
88  * @return Status type discriminator.
89  */
90  [[nodiscard]] Type get_type() const override;
91 
92  /**
93  * @brief Returns the literal @c "PublicationMatched".
94  *
95  * @return Event name string.
96  */
97  [[nodiscard]] std::string get_string() const override;
98 
99  int32_t total_count{0}; ///< Cumulative subscribers ever matched.
100  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
101  int32_t current_count{0}; ///< Subscribers currently matched.
102  int32_t current_count_change{0}; ///< Delta in @c current_count since the last notification.
103  InstanceHandle last_subscription_handle{nullptr}; ///< Opaque handle of the subscriber that triggered this event.
104 
105  /**
106  * @brief Streams the counter fields to @p ostream.
107  *
108  * @param ostream Output stream.
109  * @param status Event to print.
110  * @return Reference to @p ostream.
111  */
112  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const PublicationMatched& status) noexcept;
113 };
114 
115 /**
116  * @struct OfferedDeadlineMissed
117  * @brief Writer-side event raised when the writer fails to publish within its offered deadline.
118  *
119  * @details
120  * Fires once per missed instance; @c last_instance_handle identifies the most recent offender.
121  */
122 struct VLINK_EXPORT OfferedDeadlineMissed final : public Base {
123  public:
124  /**
125  * @brief Returns @c kOfferedDeadlineMissed.
126  *
127  * @return Status type discriminator.
128  */
129  [[nodiscard]] Type get_type() const override;
130 
131  /**
132  * @brief Returns the literal @c "OfferedDeadlineMissed".
133  *
134  * @return Event name string.
135  */
136  [[nodiscard]] std::string get_string() const override;
137 
138  int32_t total_count{0}; ///< Cumulative deadline misses across all instances.
139  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
140  InstanceHandle last_instance_handle{nullptr}; ///< Opaque handle of the instance that missed most recently.
141 
142  /**
143  * @brief Streams the counter fields to @p ostream.
144  *
145  * @param ostream Output stream.
146  * @param status Event to print.
147  * @return Reference to @p ostream.
148  */
149  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const OfferedDeadlineMissed& status) noexcept;
150 };
151 
152 /**
153  * @struct OfferedIncompatibleQos
154  * @brief Writer-side event raised when a subscriber is rejected for incompatible QoS.
155  */
156 struct VLINK_EXPORT OfferedIncompatibleQos final : public Base {
157  public:
158  /**
159  * @brief Returns @c kOfferedIncompatibleQos.
160  *
161  * @return Status type discriminator.
162  */
163  [[nodiscard]] Type get_type() const override;
164 
165  /**
166  * @brief Returns the literal @c "OfferedIncompatibleQos".
167  *
168  * @return Event name string.
169  */
170  [[nodiscard]] std::string get_string() const override;
171 
172  int32_t total_count{0}; ///< Cumulative incompatible subscribers detected.
173  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
174  int32_t last_policy_id{0}; ///< DDS QoS policy identifier that caused the rejection.
175 
176  /**
177  * @brief Streams the counter fields to @p ostream.
178  *
179  * @param ostream Output stream.
180  * @param status Event to print.
181  * @return Reference to @p ostream.
182  */
183  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const OfferedIncompatibleQos& status) noexcept;
184 };
185 
186 /**
187  * @struct LivelinessLost
188  * @brief Writer-side event raised when the liveliness lease lapses without assertion.
189  *
190  * @details
191  * Peers will consider the writer dead until liveliness is re-asserted.
192  */
193 struct VLINK_EXPORT LivelinessLost final : public Base {
194  public:
195  /**
196  * @brief Returns @c kLivelinessLost.
197  *
198  * @return Status type discriminator.
199  */
200  [[nodiscard]] Type get_type() const override;
201 
202  /**
203  * @brief Returns the literal @c "LivelinessLost".
204  *
205  * @return Event name string.
206  */
207  [[nodiscard]] std::string get_string() const override;
208 
209  int32_t total_count{0}; ///< Cumulative liveliness-lost events emitted.
210  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
211 
212  /**
213  * @brief Streams the counter fields to @p ostream.
214  *
215  * @param ostream Output stream.
216  * @param status Event to print.
217  * @return Reference to @p ostream.
218  */
219  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const LivelinessLost& status) noexcept;
220 };
221 
222 /* ================== For reader ================== */
223 
224 /**
225  * @struct SubscriptionMatched
226  * @brief Reader-side event raised when a matching publisher appears or disappears.
227  */
228 struct VLINK_EXPORT SubscriptionMatched final : public Base {
229  public:
230  /**
231  * @brief Returns @c kSubscriptionMatched.
232  *
233  * @return Status type discriminator.
234  */
235  [[nodiscard]] Type get_type() const override;
236 
237  /**
238  * @brief Returns the literal @c "SubscriptionMatched".
239  *
240  * @return Event name string.
241  */
242  [[nodiscard]] std::string get_string() const override;
243 
244  int32_t total_count{0}; ///< Cumulative publishers ever matched.
245  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
246  int32_t current_count{0}; ///< Publishers currently matched.
247  int32_t current_count_change{0}; ///< Delta in @c current_count since the last notification.
248  InstanceHandle last_publication_handle{nullptr}; ///< Opaque handle of the publisher that triggered this event.
249 
250  /**
251  * @brief Streams the counter fields to @p ostream.
252  *
253  * @param ostream Output stream.
254  * @param status Event to print.
255  * @return Reference to @p ostream.
256  */
257  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const SubscriptionMatched& status) noexcept;
258 };
259 
260 /**
261  * @struct RequestedDeadlineMissed
262  * @brief Reader-side event raised when the reader does not receive data within its requested deadline.
263  */
265  public:
266  /**
267  * @brief Returns @c kRequestedDeadlineMissed.
268  *
269  * @return Status type discriminator.
270  */
271  [[nodiscard]] Type get_type() const override;
272 
273  /**
274  * @brief Returns the literal @c "RequestedDeadlineMissed".
275  *
276  * @return Event name string.
277  */
278  [[nodiscard]] std::string get_string() const override;
279 
280  int32_t total_count{0}; ///< Cumulative deadline misses across all instances.
281  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
282  InstanceHandle last_instance_handle{nullptr}; ///< Opaque handle of the instance that missed most recently.
283 
284  /**
285  * @brief Streams the counter fields to @p ostream.
286  *
287  * @param ostream Output stream.
288  * @param status Event to print.
289  * @return Reference to @p ostream.
290  */
291  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const RequestedDeadlineMissed& status) noexcept;
292 };
293 
294 /**
295  * @struct LivelinessChanged
296  * @brief Reader-side event raised when the liveliness of a matched publisher changes.
297  *
298  * @details
299  * The @c alive_count and @c not_alive_count fields hold the current totals; the matching
300  * @c *_change fields hold the delta since the last notification.
301  */
302 struct VLINK_EXPORT LivelinessChanged final : public Base {
303  public:
304  /**
305  * @brief Returns @c kLivelinessChanged.
306  *
307  * @return Status type discriminator.
308  */
309  [[nodiscard]] Type get_type() const override;
310 
311  /**
312  * @brief Returns the literal @c "LivelinessChanged".
313  *
314  * @return Event name string.
315  */
316  [[nodiscard]] std::string get_string() const override;
317 
318  int32_t alive_count{0}; ///< Matched publishers currently considered alive.
319  int32_t not_alive_count{0}; ///< Matched publishers currently considered not alive.
320  int32_t alive_count_change{0}; ///< Delta in @c alive_count since the last notification.
321  int32_t not_alive_count_change{0}; ///< Delta in @c not_alive_count since the last notification.
322  InstanceHandle last_publication_handle{nullptr}; ///< Opaque handle of the publisher whose state changed.
323 
324  /**
325  * @brief Streams the counter fields to @p ostream.
326  *
327  * @param ostream Output stream.
328  * @param status Event to print.
329  * @return Reference to @p ostream.
330  */
331  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const LivelinessChanged& status) noexcept;
332 };
333 
334 /**
335  * @struct SampleRejected
336  * @brief Reader-side event raised when an inbound sample is dropped due to a resource limit.
337  */
338 struct VLINK_EXPORT SampleRejected final : public Base {
339  public:
340  /**
341  * @brief Reason codes describing which resource ceiling rejected the sample.
342  *
343  * | Enumerator | Meaning |
344  * | --------------------------------------- | ----------------------------------------- |
345  * | @c kNotRejected | placeholder; sample was not rejected |
346  * | @c kRejectedByInstancesLimit | @c max_instances exhausted |
347  * | @c kRejectedBySamplesLimit | @c max_samples exhausted |
348  * | @c kRejectedBySamplesPerInstanceLimit | @c max_samples_per_instance exhausted |
349  */
350  enum Kind : uint8_t {
351  kNotRejected = 0, ///< Placeholder reason; no rejection occurred.
352  kRejectedByInstancesLimit = 1, ///< Reader exhausted its instance budget.
353  kRejectedBySamplesLimit = 2, ///< Reader exhausted its total-sample budget.
354  kRejectedBySamplesPerInstanceLimit = 3 ///< Reader exhausted its per-instance budget.
355  };
356 
357  /**
358  * @brief Returns @c kSampleRejected.
359  *
360  * @return Status type discriminator.
361  */
362  [[nodiscard]] Type get_type() const override;
363 
364  /**
365  * @brief Returns the literal @c "SampleRejected".
366  *
367  * @return Event name string.
368  */
369  [[nodiscard]] std::string get_string() const override;
370 
371  int32_t total_count{0}; ///< Cumulative samples rejected.
372  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
373  Kind last_reason{kNotRejected}; ///< Reason code for the most recent rejection.
374  InstanceHandle last_instance_handle{nullptr}; ///< Opaque handle of the rejected instance.
375 
376  /**
377  * @brief Streams the counter and reason fields to @p ostream.
378  *
379  * @param ostream Output stream.
380  * @param status Event to print.
381  * @return Reference to @p ostream.
382  */
383  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const SampleRejected& status) noexcept;
384 };
385 
386 /**
387  * @struct RequestedIncompatibleQos
388  * @brief Reader-side event raised when a publisher is rejected for incompatible QoS.
389  */
391  public:
392  /**
393  * @brief Returns @c kRequestedIncompatibleQos.
394  *
395  * @return Status type discriminator.
396  */
397  [[nodiscard]] Type get_type() const override;
398 
399  /**
400  * @brief Returns the literal @c "RequestedIncompatibleQos".
401  *
402  * @return Event name string.
403  */
404  [[nodiscard]] std::string get_string() const override;
405 
406  int32_t total_count{0}; ///< Cumulative incompatible publishers detected.
407  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
408  int32_t last_policy_id{0}; ///< DDS QoS policy identifier that caused the rejection.
409 
410  /**
411  * @brief Streams the counter fields to @p ostream.
412  *
413  * @param ostream Output stream.
414  * @param status Event to print.
415  * @return Reference to @p ostream.
416  */
417  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const RequestedIncompatibleQos& status) noexcept;
418 };
419 
420 /**
421  * @struct SampleLost
422  * @brief Reader-side event raised when a sample is lost between writer and reader.
423  *
424  * @details
425  * Typically caused by writer rate exceeding the reader's @c History depth.
426  */
427 struct VLINK_EXPORT SampleLost final : public Base {
428  public:
429  /**
430  * @brief Returns @c kSampleLost.
431  *
432  * @return Status type discriminator.
433  */
434  [[nodiscard]] Type get_type() const override;
435 
436  /**
437  * @brief Returns the literal @c "SampleLost".
438  *
439  * @return Event name string.
440  */
441  [[nodiscard]] std::string get_string() const override;
442 
443  int32_t total_count{0}; ///< Cumulative samples lost.
444  int32_t total_count_change{0}; ///< Delta in @c total_count since the last notification.
445 
446  /**
447  * @brief Streams the counter fields to @p ostream.
448  *
449  * @param ostream Output stream.
450  * @param status Event to print.
451  * @return Reference to @p ostream.
452  */
453  VLINK_EXPORT friend std::ostream& operator<<(std::ostream& ostream, const SampleLost& status) noexcept;
454 };
455 
456 } // namespace Status
457 
458 } // namespace vlink
#define VLINK_EXPORT
Definition: macros.h:81
DDS-aligned status event hierarchy delivered to publisher and subscriber callbacks.