VLink  2.0.0
A high-performance communication middleware
setter-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 <string>
28 #include <utility>
29 
30 #include "../base/cpu_profiler_guard.h"
31 #include "../base/logger.h"
32 #include "../impl/url.h"
33 #include "../serializer.h"
34 #include "../setter.h"
35 
36 namespace vlink {
37 
38 template <typename ValueT, SecurityType SecT>
39 inline typename Setter<ValueT, SecT>::UniquePtr Setter<ValueT, SecT>::create_unique(const std::string& url_str,
40  InitType type) {
41  return std::make_unique<Setter<ValueT, SecT>>(url_str, type);
42 }
43 
44 template <typename ValueT, SecurityType SecT>
45 inline typename Setter<ValueT, SecT>::SharedPtr Setter<ValueT, SecT>::create_shared(const std::string& url_str,
46  InitType type) {
47  return std::make_shared<Setter<ValueT, SecT>>(url_str, type);
48 }
49 
50 template <typename ValueT, SecurityType SecT>
51 template <typename ConfT, typename>
52 inline Setter<ValueT, SecT>::Setter(const ConfT& conf, InitType type) {
53  static_assert(ConfT::get_allow_impl_type() & kImplType, "Conf does not support setter mode.");
54 
55  if VUNLIKELY (!conf.parse(kImplType) || !conf.is_valid()) {
56  VLOG_F(conf, " setter configuration is invalid or could not be parsed.");
57  return;
58  }
59 
60  this->impl_ = conf.create_setter();
61 
62  if VUNLIKELY (!this->impl_) {
63  VLOG_F(conf, " setter implementation not available for this transport.");
64  return;
65  }
66 
67  this->impl_->transport_type = conf.get_transport_type();
68  this->impl_->ser_type = Serializer::get_serialized_type<kValueType, ValueT>();
69  this->impl_->schema_type = Serializer::get_schema_type<kValueType, ValueT>();
70  this->impl_->is_cdr_type = Serializer::is_cdr_type<ValueT>();
71 
72  if constexpr (std::is_same_v<ConfT, Url>) {
73  this->impl_->url = conf.get_str();
74  }
75 
76  if constexpr (SecT == SecurityType::kWithSecurity) {
77  this->impl_->is_security_type = true;
78  }
79 
80  if VLIKELY (type == InitType::kWithInit) {
81  this->init(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
82  }
83 }
84 
85 template <typename ValueT, SecurityType SecT>
86 inline Setter<ValueT, SecT>::Setter(const std::string& url_str, InitType type)
87  : Setter<ValueT, SecT>(Url(url_str), type) {}
88 
89 template <typename ValueT, SecurityType SecT>
91  // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.VirtualCall)
92  this->deinit();
93 }
94 
95 template <typename ValueT, SecurityType SecT>
98  return false;
99  }
100 
101  this->impl_->sync([this]() {
102  std::optional<ValueT> snapshot;
103  {
104  std::lock_guard lock(mtx_);
105  snapshot = value_;
106  }
107 
108  if VLIKELY (snapshot.has_value()) {
109  write(snapshot.value());
110  }
111  });
112 
113  return true;
114 }
115 
116 template <typename ValueT, SecurityType SecT>
119 }
120 
121 template <typename ValueT, SecurityType SecT>
122 inline void Setter<ValueT, SecT>::set(const ValueT& value) {
123 #ifndef VLINK_DISABLE_PROFILER
124  CpuProfilerGuard profiler_guard(this->impl_->profiler.get());
125 #endif
126 
127  {
128  std::lock_guard lock(mtx_);
129  value_.emplace(value);
130  }
131 
132  if VUNLIKELY (!this->has_inited_.load(std::memory_order_acquire)) {
133  return;
134  }
135 
136  write(value);
137 }
138 
139 template <typename ValueT, SecurityType SecT>
141  if VUNLIKELY (this->has_inited_.load(std::memory_order_acquire)) {
142  this->impl_->deinit_ext();
143  this->impl_->impl_type = kPublisher;
144  this->impl_->init_ext();
145  } else {
146  this->impl_->impl_type = kPublisher;
147  }
148 }
149 
150 template <typename ValueT, SecurityType SecT>
151 inline void Setter<ValueT, SecT>::write(const ValueT& value) {
152  if constexpr (std::is_same_v<ValueT, Bytes>) {
153  write_bytes(value);
154  } else {
155  Bytes msg_data;
156 
157  if constexpr (SecT != SecurityType::kWithSecurity) {
158  if (this->is_support_loan_) {
159  size_t ser_size = Serializer::get_serialized_size<kValueType>(value);
160 
161  msg_data = this->impl_->loan(ser_size);
162 
163  if VUNLIKELY (ser_size != 0 && msg_data.empty()) {
164  return;
165  }
166  }
167  }
168 
169  if VUNLIKELY (!Serializer::serialize<kValueType>(value, msg_data, this->impl_->transport_type)) {
170  VLOG_T("Setter serialize failed, url: ", this->impl_->url, ".");
171 
172  if constexpr (SecT != SecurityType::kWithSecurity) {
173  if (this->is_support_loan_) {
174  this->impl_->return_loan(msg_data);
175  }
176  }
177 
178  return;
179  }
180 
181  write_bytes(msg_data);
182  }
183 }
184 
185 template <typename ValueT, SecurityType SecT>
186 inline void Setter<ValueT, SecT>::write_bytes(const Bytes& data) {
187  if constexpr (SecT == SecurityType::kWithSecurity) {
188  Bytes sec_data;
189 
190  if VUNLIKELY (!this->impl_->security || !this->impl_->security->encrypt(data, sec_data)) {
191  VLOG_T("Setter encrypt failed, url: ", this->impl_->url, ".");
192  return;
193  }
194 
195  this->impl_->write(sec_data);
196  } else {
197  this->impl_->try_record(ActionType::kSet, data);
198 
199  this->impl_->write(data);
200  }
201 }
202 
203 template <typename ValueT>
204 template <typename SecurityConfigT>
206  SecurityConfigT&& sec_cfg,
207  InitType type) {
208  static_assert(std::is_same_v<std::decay_t<SecurityConfigT>, Security::Config>,
209  "SecurityConfigT must be Security::Config.");
210 
211  return std::make_unique<SecuritySetter<ValueT>>(url_str, std::forward<SecurityConfigT>(sec_cfg), type);
212 }
213 
214 template <typename ValueT>
215 template <typename SecurityConfigT>
217  SecurityConfigT&& sec_cfg,
218  InitType type) {
219  static_assert(std::is_same_v<std::decay_t<SecurityConfigT>, Security::Config>,
220  "SecurityConfigT must be Security::Config.");
221 
222  return std::make_shared<SecuritySetter<ValueT>>(url_str, std::forward<SecurityConfigT>(sec_cfg), type);
223 }
224 
225 template <typename ValueT>
226 template <typename ConfT, typename SecurityConfigT, typename>
227 inline SecuritySetter<ValueT>::SecuritySetter(const ConfT& conf, SecurityConfigT&& sec_cfg, InitType type)
229  static_assert(std::is_same_v<std::decay_t<SecurityConfigT>, Security::Config>,
230  "SecurityConfigT must be Security::Config.");
231 
232  this->enable_security(std::forward<SecurityConfigT>(sec_cfg));
233 
234  if VLIKELY (type == InitType::kWithInit) {
235  this->init(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
236  }
237 }
238 
239 template <typename ValueT>
240 template <typename SecurityConfigT>
241 inline SecuritySetter<ValueT>::SecuritySetter(const std::string& url_str, SecurityConfigT&& sec_cfg, InitType type)
242  : Setter<ValueT, SecurityType::kWithSecurity>(url_str, InitType::kWithoutInit) {
243  static_assert(std::is_same_v<std::decay_t<SecurityConfigT>, Security::Config>,
244  "SecurityConfigT must be Security::Config.");
245 
246  this->enable_security(std::forward<SecurityConfigT>(sec_cfg));
247 
248  if VLIKELY (type == InitType::kWithInit) {
249  this->init(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
250  }
251 }
252 
253 } // namespace vlink
#define VLOG_F(...)
Definition: logger.h:791
#define VLOG_T(...)
Definition: logger.h:781
#define VUNLIKELY(...)
Short alias for VLINK_UNLIKELY.
Definition: macros.h:289
#define VLIKELY(...)
Short alias for VLINK_LIKELY.
Definition: macros.h:284