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 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_latency_and_lost_enabled(enable);
128 template <
typename MsgT, SecurityType SecT>
130 return this->impl_->is_latency_and_lost_enabled();
133 template <
typename MsgT, SecurityType SecT>
135 return this->impl_->get_latency();
138 template <
typename MsgT, SecurityType SecT>
140 return this->impl_->get_lost();
143 template <
typename MsgT, SecurityType SecT>
145 if VUNLIKELY (this->has_inited_.load(std::memory_order_acquire)) {
146 this->impl_->deinit_ext();
147 this->impl_->impl_type =
kGetter;
148 this->impl_->init_ext();
150 this->impl_->impl_type =
kGetter;
154 template <
typename MsgT, SecurityType SecT>
156 if VUNLIKELY (!this->has_inited_.load(std::memory_order_acquire)) {
157 VLOG_F(
"Subscriber::listen_bytes() called before init().");
161 if VUNLIKELY (this->impl_->is_listened) {
162 VLOG_F(
"Subscriber has already been listened, url: ", this->impl_->url,
".");
166 bool ret = this->impl_->listen([
this, callback = std::move(callback)](
const Bytes& data) {
170 if VUNLIKELY (!this->impl_->security || !this->impl_->security->decrypt(data, sec_data)) {
171 VLOG_T(
"Subscriber decrypt failed, url: ", this->impl_->url,
".");
175 this->invoke_callback(callback, sec_data);
179 this->invoke_callback(callback, data);
183 this->impl_->is_listened = ret;
188 template <
typename MsgT, SecurityType SecT>
189 inline bool Subscriber<MsgT, SecT>::listen_intra(MsgCallback&& callback) {
190 if VUNLIKELY (!this->has_inited_.load(std::memory_order_acquire)) {
191 VLOG_F(
"Subscriber::listen_intra() called before init().");
195 if VUNLIKELY (this->impl_->is_listened) {
196 VLOG_F(
"Subscriber has already been listened, url: ", this->impl_->url,
".");
200 bool ret = this->impl_->listen([
this, callback = std::move(callback)](
const IntraData& intra_data) {
201 #ifndef VLINK_DISABLE_PROFILER
206 #if defined(NDEBUG) || defined(__ANDROID__)
207 auto intra_msg = std::static_pointer_cast<typename MsgT::element_type>(intra_data);
209 auto intra_msg = std::dynamic_pointer_cast<typename MsgT::element_type>(intra_data);
213 MsgT typed_msg(std::move(intra_msg));
214 this->invoke_callback(callback, typed_msg);
216 VLOG_T(
"Subscriber get intra data failed, url: ", this->impl_->url,
".");
221 this->impl_->is_listened = ret;
226 template <
typename MsgT>
227 template <
typename SecurityConfigT>
229 SecurityConfigT&& sec_cfg,
231 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
232 "SecurityConfigT must be Security::Config.");
234 return std::make_unique<SecuritySubscriber<MsgT>>(url_str, std::forward<SecurityConfigT>(sec_cfg), type);
237 template <
typename MsgT>
238 template <
typename SecurityConfigT>
240 SecurityConfigT&& sec_cfg,
242 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
243 "SecurityConfigT must be Security::Config.");
245 return std::make_shared<SecuritySubscriber<MsgT>>(url_str, std::forward<SecurityConfigT>(sec_cfg), type);
248 template <
typename MsgT>
249 template <
typename ConfT,
typename SecurityConfigT,
typename>
252 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
253 "SecurityConfigT must be Security::Config.");
262 template <
typename MsgT>
263 template <
typename SecurityConfigT>
267 static_assert(std::is_same_v<std::decay_t<SecurityConfigT>,
Security::Config>,
268 "SecurityConfigT must be Security::Config.");
270 this->enable_security(std::forward<SecurityConfigT>(sec_cfg));
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:132
bool enable_security(const Security::Config &cfg)
Installs a Security configuration before transport initialisation.
Definition: node-inl.h:327
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:292
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:239
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:228
std::unique_ptr< SecuritySubscriber< MsgT > > UniquePtr
Owning unique-pointer alias.
Definition: subscriber.h:291
SecuritySubscriber(const ConfT &conf, SecurityConfigT &&sec_cfg={}, InitType type=InitType::kWithInit)
Constructs a SecuritySubscriber from a typed configuration object.
Definition: subscriber-inl.h:250
Type-safe topic listener for the VLink event communication model.
Definition: subscriber.h:148
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:144
bool is_latency_and_lost_enabled() const
Reports whether latency and sample-loss tracking is currently active.
Definition: subscriber-inl.h:129
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:139
std::unique_ptr< Subscriber< MsgT, SecT > > UniquePtr
Owning unique-pointer alias.
Definition: subscriber.h:150
int64_t get_latency() const
Returns the most recent end-to-end latency measurement.
Definition: subscriber-inl.h:134
void set_latency_and_lost_enabled(bool enable)
Toggles per-message latency and sample-loss measurement.
Definition: subscriber-inl.h:124
std::shared_ptr< Subscriber< MsgT, SecT > > SharedPtr
Owning shared-pointer alias.
Definition: subscriber.h:151
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:843
#define VLOG_T(...)
Definition: logger.h:833
#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:150
@ 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:115
SecurityType
Compile-time selector for the per-node message security variant.
Definition: types.h:168
@ kWithSecurity
Encrypted and authenticated transport.
Aggregate of cumulative delivered / lost sample counts.
Definition: types.h:269
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:216