VLink  2.1.0
A high-performance communication middleware
zenoh_conf.h
Go to the documentation of this file.
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 zenoh_conf.h
26  * @brief Transport configuration for the @c zenoh:// Eclipse Zenoh transport.
27  *
28  * @details
29  * @c ZenohConf binds the @c zenoh:// URL scheme to Eclipse Zenoh. The VLink
30  * backend maps the six VLink node types onto Zenoh publish/subscribe,
31  * query/queryable, liveliness and matching primitives. Generic Zenoh storage,
32  * delete, scouting and admin-space APIs are intentionally not re-exposed through
33  * this transport abstraction. Optional zenoh-c shared-memory acceleration lowers
34  * latency for large payloads exchanged between processes on the same host.
35  *
36  * @par Supported Node Types
37  *
38  * | Publisher | Subscriber | Server | Client | Getter | Setter |
39  * | :-------: | :--------: | :----: | :----: | :----: | :----: |
40  * | yes | yes | yes | yes | yes | yes |
41  *
42  * @par Routing Modes
43  *
44  * | Mode | Topology | Typical use case |
45  * | --------- | ------------------------------------------------- | ------------------------------ |
46  * | @c peer | Fully meshed P2P between participants | LAN with no router |
47  * | @c client | Connects to a router as a leaf node | Fleet edge connecting to cloud |
48  * | @c router | Forwards data for connected clients | Gateway / aggregation point |
49  *
50  * @par URL Format
51  * @code
52  * zenoh://<address>[?event=<name>&domain=<N>&qos=<profile>&depth=<N>&shm=<bool>
53  * &shm_mode=<lazy|init>&shm_size=<N>&shm_threshold=<N>
54  * &shm_loan_threshold=<N>&shm_blocking=<bool>][#<fragment>]
55  * @endcode
56  *
57  * | Component | Description |
58  * | --------------------- | ---------------------------------------------------------------------- |
59  * | @c address | Base key expression (URL host concatenated with path) |
60  * | @c event | Optional event identity included in the derived native key |
61  * | @c domain | Zenoh session/domain identifier (@c ?domain=); factory default applied |
62  * | @c qos | Named QoS profile registered via @c register_qos() |
63  * | @c depth | TX queue override; @c 0 uses the QoS-selected history depth |
64  * | @c shm | Enable Zenoh shared-memory acceleration (boolean) |
65  * | @c shm_mode | Pool init strategy; @c lazy or @c init |
66  * | @c shm_size | SHM pool size; accepts bytes, K, M, or G suffixes |
67  * | @c shm_threshold | Minimum payload size to switch the SHM path on |
68  * | @c shm_loan_threshold | Minimum size for VLink SHM loan buffers |
69  * | @c shm_blocking | Whether @c loan() blocks when the pool is exhausted |
70  * | @c fragment | Optional transport hint or session-config fragment |
71  *
72  * @par QoS Registration
73  * @code
74  * vlink::Qos qos;
75  * qos.valid = true;
76  * qos.reliability.kind = vlink::Qos::Reliability::kReliable;
77  * vlink::ZenohConf::register_qos("reliable", qos);
78  *
79  * auto pub = vlink::Publisher<MyMsg>::create_unique("zenoh://vehicle/speed?qos=reliable");
80  * @endcode
81  *
82  * @note Compiled only when @c VLINK_SUPPORT_ZENOH is defined.
83  * @note @c is_valid() returns @c false when @c address is empty, @c domain is negative,
84  * or @c depth is negative.
85  * @note Zenoh consumes only the profile's reliability/congestion hint, priority,
86  * express flag and positive history depth; other @c Qos fields remain DDS-only.
87  * @note The zenoh-pico build must enable local subscriber and local queryable
88  * support because VLink intentionally reuses compatible sessions.
89  */
90 
91 #pragma once
92 
93 #ifdef VLINK_SUPPORT_ZENOH
94 
95 #include <cstdint>
96 #include <functional>
97 #include <map>
98 #include <shared_mutex>
99 #include <string>
100 
101 #include "../extension/qos.h"
102 #include "../impl/conf.h"
103 
104 namespace vlink {
105 
106 /**
107  * @struct ZenohConf
108  * @brief Concrete @c Conf describing a Zenoh endpoint addressed by a @c zenoh:// URL.
109  *
110  * @details
111  * Stores the Zenoh base key expression, an optional event identity, the session
112  * domain identifier, an optional named QoS profile and depth override, plus the
113  * tunable SHM-acceleration knobs exposed through URL query keys.
114  */
115 struct VLINK_EXPORT ZenohConf final : public Conf {
116  std::string address; ///< Base key expression (URL host concatenated with path).
117  std::string event; ///< Optional event identity included in the native key.
118  int32_t domain{0}; ///< Zenoh session / domain identifier (non-negative).
119  int32_t depth{0}; ///< TX queue override; @c 0 uses the QoS-selected history depth.
120  std::string qos; ///< Named QoS profile key registered via @c register_qos().
121  std::string fragment; ///< Optional transport hint or session-config fragment.
122  std::string shm; ///< Optional SHM acceleration enable (string boolean).
123  std::string shm_mode; ///< Optional SHM pool init strategy; @c lazy or @c init.
124  std::string shm_size; ///< Optional SHM pool size; accepts bytes, K, M, or G suffixes.
125  std::string shm_threshold; ///< Optional minimum payload size before SHM path engages.
126  std::string shm_loan_threshold; ///< Optional minimum size for VLink SHM loan buffers.
127  std::string shm_blocking; ///< Optional blocking behaviour for @c loan() when the pool is full.
128 
129  /**
130  * @brief Builds a @c ZenohConf from the URL's primary fields.
131  *
132  * @param _address Base key expression.
133  * @param _event Optional event identity; empty by default.
134  * @param _domain Domain identifier; defaults to @c 0.
135  * @param _qos Named QoS profile key; empty by default.
136  * @param _fragment Optional transport-hint fragment; empty by default.
137  */
138  explicit ZenohConf(const std::string& _address, const std::string& _event = "", int32_t _domain = 0,
139  const std::string& _qos = "", const std::string& _fragment = "");
140 
141  /**
142  * @brief Component-wise equality on all configuration fields, including SHM tunables.
143  *
144  * @param conf Configuration to compare with.
145  * @return @c true when every field of @c *this matches @p conf.
146  */
147  [[nodiscard]] bool operator==(const ZenohConf& conf) const noexcept;
148 
149  /**
150  * @brief Logical negation of @c operator==.
151  *
152  * @param conf Configuration to compare with.
153  * @return @c true when any field differs from @p conf.
154  */
155  [[nodiscard]] bool operator!=(const ZenohConf& conf) const noexcept;
156 
157  /**
158  * @brief Reports this object's transport tag.
159  *
160  * @return @c TransportType::kZenoh.
161  */
162  [[nodiscard]] TransportType get_transport_type() const override;
163 
164  /**
165  * @brief Copies non-empty Zenoh SHM tunables into a property map.
166  *
167  * @details
168  * Lets URL-supplied @c shm* query keys and explicit @c set_property("zenoh.*", ...)
169  * calls share the same factory property path without enlarging the factory key set.
170  *
171  * @param properties Destination property map; entries are added for each non-empty SHM field.
172  */
173  void append_properties(PropertiesMap& properties) const;
174 
175  /**
176  * @brief Registers a named QoS profile that endpoints may reference via @c ?qos=.
177  *
178  * @details
179  * Profile names share a global namespace. Collisions with reserved tokens
180  * (@c part, @c topic, @c pub, @c sub, @c writer, @c reader) or with an
181  * already registered profile abort with a fatal log entry.
182  *
183  * @param name Unique profile key; must not collide with any reserved token.
184  * @param qos @c Qos value associated with the key.
185  */
186  static void register_qos(const std::string& name, const Qos& qos);
187 
188  private:
189  static void register_qos_internal(const std::string& name, const Qos& qos);
190 
191  static const Qos& find_qos(const std::string& name);
192 
193  friend class ZenohFactory;
194  static std::map<std::string, Qos> qos_map_;
195  static std::shared_mutex mtx_;
196  static constexpr const char* kRespSuffix{"___resp"};
197 #ifndef VLINK_ENABLE_C_INTERFACE
199 #endif
201  VLINK_CONF_IMPL(ZenohConf)
202 };
203 
204 ////////////////////////////////////////////////////////////////
205 /// Details
206 ////////////////////////////////////////////////////////////////
207 
208 inline ZenohConf::ZenohConf(const std::string& _address, const std::string& _event, int32_t _domain,
209  const std::string& _qos, const std::string& _fragment)
210  : address(_address), event(_event), domain(_domain), qos(_qos), fragment(_fragment) {}
211 
212 inline bool ZenohConf::operator==(const ZenohConf& conf) const noexcept {
213  return address == conf.address && event == conf.event && domain == conf.domain && depth == conf.depth &&
214  qos == conf.qos && fragment == conf.fragment && shm == conf.shm && shm_mode == conf.shm_mode &&
215  shm_size == conf.shm_size && shm_threshold == conf.shm_threshold &&
216  shm_loan_threshold == conf.shm_loan_threshold && shm_blocking == conf.shm_blocking;
217 }
218 
219 inline bool ZenohConf::operator!=(const ZenohConf& conf) const noexcept { return !(*this == conf); }
220 
221 inline TransportType ZenohConf::get_transport_type() const { return TransportType::kZenoh; }
222 
223 inline void ZenohConf::append_properties(PropertiesMap& properties) const {
224  if (!shm.empty()) {
225  properties["zenoh.shm"] = shm;
226  }
227 
228  if (!shm_mode.empty()) {
229  properties["zenoh.shm_mode"] = shm_mode;
230  }
231 
232  if (!shm_size.empty()) {
233  properties["zenoh.shm_size"] = shm_size;
234  }
235 
236  if (!shm_threshold.empty()) {
237  properties["zenoh.shm_threshold"] = shm_threshold;
238  }
239 
240  if (!shm_loan_threshold.empty()) {
241  properties["zenoh.shm_loan_threshold"] = shm_loan_threshold;
242  }
243 
244  if (!shm_blocking.empty()) {
245  properties["zenoh.shm_blocking"] = shm_blocking;
246  }
247 }
248 
249 } // namespace vlink
250 
251 #endif
#define VLINK_CONF_IMPL(classname)
Convenience macro that emits the standard concrete conf boilerplate.
Definition: conf.h:250
#define VLINK_DECLARE_GLOBAL_PROPERTY()
Declares per-transport static configuration storage and access helpers.
Definition: conf.h:308
#define VLINK_ALLOW_IMPL_TYPE(type)
Records the bitmask of ImplType values supported by a conf.
Definition: conf.h:291
#define VLINK_EXPORT
Definition: macros.h:81