30 #include "../base/cpu_profiler_guard.h"
31 #include "../base/logger.h"
32 #include "../impl/url.h"
33 #include "../serializer.h"
34 #include "../subscriber.h"
38 template <
typename MsgT, SecurityType SecT>
41 return std::make_unique<Subscriber<MsgT, SecT>>(url_str, type);
44 template <
typename MsgT, SecurityType SecT>
47 return std::make_shared<Subscriber<MsgT, SecT>>(url_str, type);
50 template <
typename MsgT, SecurityType SecT>
51 template <
typename ConfT,
typename>
53 static_assert(ConfT::get_allow_impl_type() & kImplType,
"Conf does not support subscriber mode.");
55 if VUNLIKELY (!conf.parse(kImplType) || !conf.is_valid()) {
56 VLOG_F(conf,
" subscriber configuration is invalid or could not be parsed.");
60 this->impl_ = conf.create_subscriber();
63 VLOG_F(conf,
" subscriber implementation not available for this transport.");
67 this->impl_->transport_type = conf.get_transport_type();
68 this->impl_->ser_type = Serializer::get_serialized_type<kMsgType, MsgT>();
69 this->impl_->schema_type = Serializer::get_schema_type<kMsgType, MsgT>();
70 this->impl_->is_cdr_type = Serializer::is_cdr_type<MsgT>();
72 if constexpr (std::is_same_v<ConfT, Url>) {
73 this->impl_->url = conf.get_str();
77 this->impl_->is_security_type =
true;
85 template <
typename MsgT, SecurityType SecT>
89 template <
typename MsgT, SecurityType SecT>
92 if constexpr (std::is_base_of_v<IntraDataType, typename MsgT::element_type>) {
96 return listen_intra(std::move(callback));
101 return listen_bytes([
this, callback = std::move(callback)](
const Bytes& data) {
102 #ifndef VLINK_DISABLE_PROFILER
106 if constexpr (std::is_same_v<MsgT, Bytes>) {
111 thread_local
auto msg = this->
template get_default_value<MsgT>();
113 if VUNLIKELY (!Serializer::deserialize<kMsgType>(data, msg, this->impl_->transport_type)) {
114 VLOG_T(
"Subscriber deserialize failed, url: ", this->impl_->url,
".");
123 template <
typename MsgT, SecurityType SecT>
125 this->impl_->set_manual_unloan(manual_unloan);
126 this->is_manual_unloan_ = manual_unloan;
129 template <
typename MsgT, SecurityType SecT>
131 this->impl_->set_latency_and_lost_enabled(enable);
134 template <
typename MsgT, SecurityType SecT>
136 return this->impl_->is_latency_and_lost_enabled();
139 template <
typename MsgT, SecurityType SecT>
141 return this->impl_->get_latency();
144 template <
typename MsgT, SecurityType SecT>
146 return this->impl_->get_lost();
149 template <
typename MsgT, SecurityType SecT>
151 if VUNLIKELY (this->has_inited_.load(std::memory_order_acquire)) {
152 this->impl_->deinit_ext();
153 this->impl_->impl_type =
kGetter;
154 this->impl_->init_ext();
156 this->impl_->impl_type =
kGetter;
160 template <
typename MsgT, SecurityType SecT>
162 if VUNLIKELY (!this->has_inited_.load(std::memory_order_acquire)) {
163 VLOG_F(
"Subscriber::listen_bytes() called before init().");
167 if VUNLIKELY (this->impl_->is_listened) {
168 VLOG_F(
"Subscriber has already been listened, url: ", this->impl_->url,
".");
172 bool ret = this->impl_->listen([
this, callback = std::move(callback)](
const Bytes& data) {
176 if VUNLIKELY (!this->impl_->security || !this->impl_->security->decrypt(data, sec_data)) {
177 VLOG_T(
"Subscriber decrypt failed, url: ", this->impl_->url,
".");
181 this->invoke_callback(callback, sec_data);
185 this->invoke_callback(callback, data);
189 this->impl_->is_listened = ret;
194 template <
typename MsgT, SecurityType SecT>
196 if VUNLIKELY (!this->has_inited_.load(std::memory_order_acquire)) {
197 VLOG_F(
"Subscriber::listen_intra() called before init().");
201 if VUNLIKELY (this->impl_->is_listened) {
202 VLOG_F(
"Subscriber has already been listened, url: ", this->impl_->url,
".");
206 bool ret = this->impl_->listen([
this, callback = std::move(callback)](
const IntraData& intra_data) {
207 #ifndef VLINK_DISABLE_PROFILER
208 CpuProfilerGuard profiler_guard(this->impl_->profiler.get());
211 if constexpr (Traits::IsSharedPtr<MsgT>()) {
212 #if defined(NDEBUG) || defined(__ANDROID__)
213 auto intra_msg = std::static_pointer_cast<typename MsgT::element_type>(intra_data);
215 auto intra_msg = std::dynamic_pointer_cast<typename MsgT::element_type>(intra_data);
219 MsgT typed_msg(std::move(intra_msg));
220 this->invoke_callback(callback, typed_msg);
222 VLOG_T(
"Subscriber get intra data failed, url: ", this->impl_->url,
".");
227 this->impl_->is_listened = ret;
232 template <
typename MsgT>
233 template <
typename SecurityConfigT>
235 SecurityConfigT&& sec_cfg,
237 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
238 "SecurityConfigT must be Security::Config.");
240 return std::make_unique<SecuritySubscriber<MsgT>>(url_str, std::forward<SecurityConfigT>(sec_cfg), type);
243 template <
typename MsgT>
244 template <
typename SecurityConfigT>
246 SecurityConfigT&& sec_cfg,
248 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
249 "SecurityConfigT must be Security::Config.");
251 return std::make_shared<SecuritySubscriber<MsgT>>(url_str, std::forward<SecurityConfigT>(sec_cfg), type);
254 template <
typename MsgT>
255 template <
typename ConfT,
typename SecurityConfigT,
typename>
258 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
259 "SecurityConfigT must be Security::Config.");
268 template <
typename MsgT>
269 template <
typename SecurityConfigT>
273 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
274 "SecurityConfigT must be Security::Config.");
276 this->enable_security(std::forward<SecurityConfigT>(sec_cfg));
278 if VLIKELY (type == InitType::kWithInit) {
Fixed-size 128-byte buffer holder with SBO, five ownership modes and integrated codecs.
Definition: bytes.h:120
Scope guard that opens and closes a CpuProfiler active interval.
Definition: cpu_profiler_guard.h:80
Copyable type-erased callable analogue of std::function with a tunable SBO and pool spill.
Definition: functional.h:131
bool enable_security(const Security::Config &cfg)
Installs a Security configuration before transport initialisation.
Definition: node-inl.h:321
virtual bool init()
Initialises the node and its transport back-end.
Definition: node-inl.h:39
std::shared_ptr< SecuritySubscriber< MsgT > > SharedPtr
Owning shared-pointer alias.
Definition: subscriber.h:296
static SharedPtr create_shared(const std::string &url_str, SecurityConfigT &&sec_cfg={}, InitType type=InitType::kWithInit)
Heap-allocates a SecuritySubscriber and wraps it in a std::shared_ptr.
Definition: subscriber-inl.h:245
static UniquePtr create_unique(const std::string &url_str, SecurityConfigT &&sec_cfg={}, InitType type=InitType::kWithInit)
Heap-allocates a SecuritySubscriber and wraps it in a std::unique_ptr.
Definition: subscriber-inl.h:234
std::unique_ptr< SecuritySubscriber< MsgT > > UniquePtr
Owning unique-pointer alias.
Definition: subscriber.h:295
SecuritySubscriber(const ConfT &conf, SecurityConfigT &&sec_cfg={}, InitType type=InitType::kWithInit)
Constructs a SecuritySubscriber from a typed configuration object.
Definition: subscriber-inl.h:256
Type-safe topic listener for the VLink event communication model.
Definition: subscriber.h:142
bool listen(MsgCallback &&callback)
Installs the receive callback that runs for every inbound message.
Definition: subscriber-inl.h:90
static UniquePtr create_unique(const std::string &url_str, InitType type=InitType::kWithInit)
Heap-allocates a Subscriber and wraps it in a std::unique_ptr.
Definition: subscriber-inl.h:39
void mark_as_getter()
Promotes this subscriber to behave as a Getter (field-reader) at the transport layer.
Definition: subscriber-inl.h:150
bool is_latency_and_lost_enabled() const
Reports whether latency and sample-loss tracking is currently active.
Definition: subscriber-inl.h:135
static SharedPtr create_shared(const std::string &url_str, InitType type=InitType::kWithInit)
Heap-allocates a Subscriber and wraps it in a std::shared_ptr.
Definition: subscriber-inl.h:45
SampleLostInfo get_lost() const
Returns cumulative sample-delivery statistics.
Definition: subscriber-inl.h:145
std::unique_ptr< Subscriber< MsgT, SecT > > UniquePtr
Owning unique-pointer alias.
Definition: subscriber.h:144
int64_t get_latency() const
Returns the most recent end-to-end latency measurement.
Definition: subscriber-inl.h:140
void set_latency_and_lost_enabled(bool enable)
Toggles per-message latency and sample-loss measurement.
Definition: subscriber-inl.h:130
std::shared_ptr< Subscriber< MsgT, SecT > > SharedPtr
Owning shared-pointer alias.
Definition: subscriber.h:145
void set_manual_unloan(bool manual_unloan) override
Enables or disables manual-unloan mode for zero-copy receives.
Definition: subscriber-inl.h:124
Subscriber(const ConfT &conf, InitType type=InitType::kWithInit)
Constructs a subscriber from a typed transport configuration object.
Definition: subscriber-inl.h:52
#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
InitType
Selects between immediate and deferred node initialisation.
Definition: types.h:154
@ kWithoutInit
Defer initialisation; call init() manually.
@ kWithInit
Initialise immediately in the constructor.
@ kSubscribe
Message observed by a Subscriber node.
std::shared_ptr< IntraDataType > IntraData
Shared-ownership handle for an IntraDataType payload.
Definition: intra_data.h:112
@ kIntra
In-process queue (intra://).
@ kGetter
Field getter (reads latest value).
Definition: types.h:117
SecurityType
Compile-time selector for the per-node message security variant.
Definition: types.h:172
@ kWithSecurity
Encrypted and authenticated transport.
Aggregate of cumulative delivered / lost sample counts.
Definition: types.h:273
Aggregate of every parameter accepted by the Security constructor.
Definition: security.h:164
Detects whether T is (or derives from) a std::shared_ptr specialisation.
Definition: traits.h:193
Conf subclass that routes virtual calls to the transport selected by a URL string.
Definition: url.h:213