VLink 2.0.0
A high-performance communication middleware
载入中...
搜索中...
未找到
node-inl.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#pragma once
25
26#include <memory>
27#include <mutex>
28#include <string>
29#include <utility>
30
31#include "../base/logger.h"
32#include "../impl/types.h"
33#include "../node.h"
34#include "../version.h"
35
36namespace vlink {
37
38template <typename ImplT, SecurityType SecT>
40 bool expected = false;
41
42 if VUNLIKELY (!has_inited_.compare_exchange_strong(expected, true)) {
43 return false;
44 }
45
47
48 impl_->init();
49 impl_->init_ext();
50
51 is_support_loan_ = impl_->is_support_loan();
52
53 return true;
54}
55
56template <typename ImplT, SecurityType SecT>
58 bool expected = true;
59
60 if VUNLIKELY (!has_inited_.compare_exchange_strong(expected, false)) {
61 return false;
62 }
63
64 interrupt(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
65
66 if (quit_mtx_.has_value()) {
67 std::lock_guard quit_lock(quit_mtx_.value());
68 impl_->deinit();
69 impl_->deinit_ext();
70 } else {
71 impl_->deinit();
72 impl_->deinit_ext();
73 }
74
75 return true;
76}
77
78template <typename ImplT, SecurityType SecT>
79inline bool Node<ImplT, SecT>::has_inited() const {
80 return has_inited_;
81}
82
83template <typename ImplT, SecurityType SecT>
85 return impl_->is_support_loan();
86}
87
88template <typename ImplT, SecurityType SecT>
89inline Bytes Node<ImplT, SecT>::loan(int64_t size) {
90 Bytes bytes = impl_->loan(size);
91
92 return bytes;
93}
94
95template <typename ImplT, SecurityType SecT>
96inline bool Node<ImplT, SecT>::return_loan(const Bytes& bytes) {
97 return impl_->return_loan(bytes);
98}
99
100template <typename ImplT, SecurityType SecT>
101inline void Node<ImplT, SecT>::set_manual_unloan(bool manual_unloan) {
102 (void)manual_unloan;
103 VLOG_W("Node: Function [set_manual_unloan] is not supported.");
104}
105
106template <typename ImplT, SecurityType SecT>
108 return is_manual_unloan_;
109}
110
111template <typename ImplT, SecurityType SecT>
113 return impl_->suspend();
114}
115
116template <typename ImplT, SecurityType SecT>
118 return impl_->resume();
119}
120
121template <typename ImplT, SecurityType SecT>
122inline bool Node<ImplT, SecT>::is_suspend() const {
123 return impl_->is_suspend();
124}
125
126template <typename ImplT, SecurityType SecT>
127inline bool Node<ImplT, SecT>::attach(class MessageLoop* message_loop) {
128 return impl_->attach(message_loop);
129}
130
131template <typename ImplT, SecurityType SecT>
133 return impl_->detach();
134}
135
136template <typename ImplT, SecurityType SecT>
138 return impl_->get_message_loop();
139}
140
141template <typename ImplT, SecurityType SecT>
143 return impl_->interrupt();
144}
145
146template <typename ImplT, SecurityType SecT>
148 return impl_->get_abstract_node();
149}
150
151template <typename ImplT, SecurityType SecT>
153 return impl_->get_status(type);
154}
156template <typename ImplT, SecurityType SecT>
158 impl_->register_status_handler(std::move(callback));
159}
160
161template <typename ImplT, SecurityType SecT>
162inline void Node<ImplT, SecT>::set_property(const std::string& prop, const std::string& value) {
163 impl_->set_property(prop, value);
164}
165
166template <typename ImplT, SecurityType SecT>
167inline std::string Node<ImplT, SecT>::get_property(const std::string& prop) const {
168 return impl_->get_property(prop);
169}
170
171template <typename ImplT, SecurityType SecT>
173 return impl_->transport_type;
175
176template <typename ImplT, SecurityType SecT>
177inline const std::string& Node<ImplT, SecT>::get_url() const {
178 return impl_->url;
179}
180
181template <typename ImplT, SecurityType SecT>
182inline void Node<ImplT, SecT>::set_security_key(const std::string& key) {
183 static_assert(SecT == SecurityType::kWithSecurity, "Must be security type.");
184
185 if VUNLIKELY (impl_->transport_type == TransportType::kIntra ||
186 (impl_->transport_type == TransportType::kDds && impl_->is_cdr_type)) {
187 VLOG_F("Node: Intra or Dds(cdr) type does not support security.");
188 }
189
190 security_->set_key(key);
191}
192
193template <typename ImplT, SecurityType SecT>
194inline void Node<ImplT, SecT>::set_record_path(const std::string& path) {
195 if VUNLIKELY (impl_->transport_type == TransportType::kIntra ||
196 (impl_->transport_type == TransportType::kDds && impl_->is_cdr_type)) {
197 VLOG_F("Node: Intra or Dds(cdr) type does not support record.");
198 }
199
200 impl_->set_record_path(path);
201}
202
203template <typename ImplT, SecurityType SecT>
205 Security::Callback&& decrypt_callback) {
206 static_assert(SecT == SecurityType::kWithSecurity, "Must be security type.");
207
208 security_->set_callbacks(std::move(encrypt_callback), std::move(decrypt_callback));
209}
210
211template <typename ImplT, SecurityType SecT>
212inline void Node<ImplT, SecT>::set_ser_type(const std::string& ser_type, SchemaType schema_type) {
213 auto next_schema_type = impl_->schema_type;
214
215 if (ser_type.empty()) {
216 next_schema_type = SchemaType::kUnknown;
217 } else if (SchemaData::is_valid_type(schema_type) && schema_type != SchemaType::kUnknown) {
218 next_schema_type = schema_type;
219 } else {
220 const auto inferred_schema_type = SchemaData::infer_ser_type(ser_type);
221
222 if (inferred_schema_type != SchemaType::kUnknown) {
223 next_schema_type = inferred_schema_type;
224 } else if (impl_->schema_type == SchemaType::kRaw || impl_->schema_type == SchemaType::kZeroCopy) {
225 next_schema_type = SchemaType::kUnknown;
226 }
227 }
228
229 const bool ser_changed = impl_->ser_type != ser_type;
230 const bool schema_changed = impl_->schema_type != next_schema_type;
231
232 if VLIKELY (!ser_changed && !schema_changed) {
233 return;
234 }
235
236 if VUNLIKELY (ser_changed && !impl_->ser_type.empty() && !ser_type.empty()) {
237 CLOG_W("Node: Enforce serialization type [%s] => [%s].", impl_->ser_type.c_str(), ser_type.c_str());
238 }
239
240 if VUNLIKELY (schema_changed && SchemaData::is_real_type(impl_->schema_type) &&
241 SchemaData::is_real_type(next_schema_type)) {
242 CLOG_W("Node: Enforce schema type [%d] => [%d].", static_cast<int>(impl_->schema_type),
243 static_cast<int>(next_schema_type));
244 }
245
246 if VUNLIKELY (has_inited_) {
247 impl_->deinit_ext();
248 }
249
250 impl_->ser_type = ser_type;
251 impl_->schema_type = next_schema_type;
252
254 impl_->init_ext();
255 }
256}
258template <typename ImplT, SecurityType SecT>
259inline const std::string& Node<ImplT, SecT>::get_ser_type() const {
260 return impl_->ser_type;
261}
262
263template <typename ImplT, SecurityType SecT>
265 return impl_->schema_type;
266}
267
268template <typename ImplT, SecurityType SecT>
271 impl_->deinit_ext();
272 impl_->set_discovery_enabled(enable);
273 impl_->init_ext();
274 } else {
275 impl_->set_discovery_enabled(enable);
276 }
277}
278
279template <typename ImplT, SecurityType SecT>
281 return impl_->get_discovery_enabled();
282}
283
284template <typename ImplT, SecurityType SecT>
285inline void Node<ImplT, SecT>::bind_proto_arena(void* proto_arena) {
286 proto_arena_ = proto_arena;
287}
289template <typename ImplT, SecurityType SecT>
290inline double Node<ImplT, SecT>::get_cpu_usage() const {
291 if (impl_->profiler) {
292 return impl_->profiler->get();
293 } else {
294 return -1;
295 }
296}
297
298template <typename ImplT, SecurityType SecT>
300 return quit_mtx_.has_value();
302
303template <typename ImplT, SecurityType SecT>
304inline void Node<ImplT, SecT>::set_safety_quit(bool safety_quit) {
305 if (safety_quit) {
306 if (!quit_mtx_.has_value()) {
307 quit_mtx_.emplace();
308 }
309 } else {
310 if (quit_mtx_.has_value()) {
311 quit_mtx_.reset();
312 }
313 }
314}
315
316template <typename ImplT, SecurityType SecT>
318 impl_->set_ssl_options(options);
319}
320
321template <typename ImplT, SecurityType SecT>
323 static_assert(std::is_base_of_v<NodeImpl, ImplT>, "ImplT must be derived from NodeImpl.");
324}
325
326template <typename ImplT, SecurityType SecT>
328 deinit(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
329}
330
331template <typename ImplT, SecurityType SecT>
333 static_assert(SecT == SecurityType::kWithSecurity, "Must be security type.");
334
335 if VUNLIKELY (impl_->transport_type == TransportType::kIntra ||
336 (impl_->transport_type == TransportType::kDds && impl_->is_cdr_type)) {
337 VLOG_F("Node: Intra or Dds(cdr) type does not support security.");
338 }
339
340 security_.emplace();
342
343template <typename ImplT, SecurityType SecT>
344template <typename CallbackT, typename... ArgsT>
345inline void Node<ImplT, SecT>::invoke_callback(const CallbackT& callback, ArgsT&&... args) {
346 if VUNLIKELY (quit_mtx_.has_value()) {
347 std::lock_guard quit_lock(quit_mtx_.value());
348 std::invoke(callback, std::forward<ArgsT>(args)...);
349 } else {
350 std::invoke(callback, std::forward<ArgsT>(args)...);
351 }
352}
353
354template <typename ImplT, SecurityType SecT>
355template <typename TypeT>
357 if constexpr (Traits::IsSharedPtr<TypeT>()) {
358 return std::make_shared<typename TypeT::element_type>();
359 } else if constexpr (Serializer::is_proto_ptr_type<TypeT>()) {
360 if VLIKELY (this->proto_arena_) {
362 static_cast<google::protobuf::Arena*>(this->proto_arena_));
363 }
364
365 VLOG_F("Node: Proto arena is not bound, url: ", this->impl_->url, ".");
366
367 return nullptr;
368 } else if constexpr (std::is_default_constructible_v<TypeT>) {
369 return TypeT{};
370 } else {
371 static_assert(Traits::ExpectFalse<TypeT>(), "TypeT is not default constructible.");
372 return {};
373 }
374}
375
376} // namespace vlink
Global singleton logger with three output styles and pluggable backends.
#define VLOG_F(...)
定义 logger.h:856
#define VLOG_W(...)
定义 logger.h:852
#define CLOG_W(...)
定义 logger.h:864
#define VUNLIKELY(...)
Shorthand alias for VLINK_UNLIKELY. Hints that the expression is unlikely true.
定义 macros.h:302
#define VLIKELY(...)
Shorthand alias for VLINK_LIKELY. Hints that the expression is likely true.
定义 macros.h:297
Base CRTP template for all VLink communication nodes.
定义 serializer-inl.h:97
static T * Create(Arena *)
定义 serializer-inl.h:99
Core type definitions shared across all VLink node implementations.
VLink library version constants, build-time feature flags, and version comparison macros.
#define VLINK_VERSION_PATCH
定义 version.h:57
#define VLINK_VERSION_MAJOR
定义 version.h:55
#define VLINK_VERSION_MINOR
定义 version.h:56