rad 6.2.0
Loading...
Searching...
No Matches
requestor.hpp
Go to the documentation of this file.
1
9#ifndef RAD_MAL_REQUESTOR_HPP
10#define RAD_MAL_REQUESTOR_HPP
11
12#include <type_traits>
13
14#include <rad/logger.hpp>
15#include <rad/mal/utils.hpp>
16#include <rad/smAdapter.hpp>
17
18#include <mal/Cii.hpp>
19#include <mal/Mal.hpp>
20#include <mal/utility/LoadMal.hpp>
21#include <mal/rr/qos/QoS.hpp>
22#include <mal/rr/qos/ReplyTime.hpp>
23#include <mal/rr/qos/ConnectionTime.hpp>
24
25namespace rad {
26
27/*
28 * Forward declaration to avoid dependency with rad.sm.
29 */
30class SMAdapter;
31
32namespace cii {
33
41template <typename INTERFACE_TYPE>
42class Requestor {
43 public:
52 Requestor(const elt::mal::Uri& uri,
53 const std::vector<std::shared_ptr<elt::mal::rr::qos::QoS>>& qos,
54 const std::optional<elt::mal::Mal::Properties> mal_properties = {})
55 : m_client() {
57
58 m_client = elt::mal::CiiFactory::getInstance().getClient<INTERFACE_TYPE>(
59 uri, qos, mal_properties.value_or(elt::mal::Mal::Properties()));
60 LOG4CPLUS_DEBUG(GetLogger(), "Created MAL client for <" << uri << ">");
61 }
62
69 explicit Requestor(const elt::mal::Uri& uri,
70 const std::optional<elt::mal::Mal::Properties> mal_properties = {})
71 : Requestor(uri, elt::mal::rr::qos::QoS::DEFAULT, mal_properties) {}
72
73
80 std::shared_ptr<INTERFACE_TYPE>& GetInterface() {
82 return m_client;
83 }
84
85 Requestor(const Requestor&) = delete;
86 Requestor& operator=(const Requestor&) = delete;
87
88 private:
89 std::shared_ptr<INTERFACE_TYPE> m_client; // Share pointer to MAL Client
90};
91
103template <class EVENT, class T>
104void RoutePartialReply(std::shared_ptr<::elt::mal::rr::Ami<T>> ami, rad::SMAdapter& sm) {
105 ::elt::mal::future<T> fut = ami->next();
106 fut.then([=, &sm](::elt::mal::future<T> fut) {
107 try {
108 LOG4CPLUS_DEBUG(GetLogger(),
109 "Received async partial reply, triggering associated event <"
110 << typeid(EVENT).name() << ">");
111 sm.PostEvent(std::make_unique<EVENT>(fut.get()));
112 LOG4CPLUS_DEBUG(GetLogger(),
113 "Received async partial reply, triggering associated event - done!");
114 if (ami->isDone() == false) {
115 RoutePartialReply<EVENT, T>(ami, sm);
116 LOG4CPLUS_DEBUG(GetLogger(),
117 "Invoked RoutePartialReply for the next partial/final reply");
118 }
119 } catch (...) {
120 LOG4CPLUS_ERROR(GetLogger(), "Unknown exception when receiving partial reply");
121 }
122 });
123 LOG4CPLUS_DEBUG(log4cplus::Logger::getInstance(rad::LOGGER_NAME), "Installed AMI continuation");
124}
125
137template <class EVENT, class FUT>
139 CancellationToken token;
140 rep_future.then([&](FUT res) {
141 if (token.IsCancelled()) {
142 return;
143 }
144 try {
145 LOG4CPLUS_DEBUG(GetLogger(), "Received async reply, triggering associated event <"
146 << typeid(EVENT).name() << ">");
147 sm.PostEvent(std::make_unique<EVENT>(res));
148 LOG4CPLUS_DEBUG(GetLogger(),
149 "Received async reply, triggering associated event - done!");
150 } catch (...) {
151 LOG4CPLUS_ERROR(GetLogger(), "Unknown exception when receiving the reply");
152 }
153 });
154 LOG4CPLUS_DEBUG(GetLogger(), "Installed future continuation");
155 return token;
156}
157
170template <class EVENT, class EVENT_ERR, class FUT>
172 CancellationToken token;
173 rep_future.then([&, token](FUT res) {
174 if (token.IsCancelled()) {
175 return;
176 }
177 try {
178 if (res.has_value()) {
179 // NOLINTNEXTLINE
180 if constexpr (std::is_void<typename FUT::value_type>::value) {
181 LOG4CPLUS_DEBUG(GetLogger(),
182 "Received async VOID reply, triggering associated event <"
183 << typeid(EVENT).name() << ">");
184 sm.PostEvent(std::make_unique<EVENT>());
185 } else {
186 // LOG4CPLUS_DEBUG(GetLogger(), "Received async reply <" << res.get() << ">,
187 // triggering associated event <" << typeid(EVENT).name() << ">");
188 LOG4CPLUS_DEBUG(GetLogger(),
189 "Received async reply, triggering associated event <"
190 << typeid(EVENT).name() << ">");
191 sm.PostEvent(std::make_unique<EVENT>(res.get()));
192 }
193 LOG4CPLUS_DEBUG(GetLogger(),
194 "Received async reply, triggering associated event - done!");
195 } else if (res.has_exception()) {
196 LOG4CPLUS_DEBUG(GetLogger(), "Exception waiting for reply");
197 sm.PostEvent(std::make_unique<EVENT_ERR>(res.get_exception_ptr()));
198 } else {
199 RAD_ASSERTNEVER();
200 }
201 } catch (...) {
202 LOG4CPLUS_ERROR(GetLogger(), "Unknown exception when receiving the reply");
203 }
204 });
205 LOG4CPLUS_DEBUG(GetLogger(), "Installed future continuation");
206 return token;
207}
208
223template <class EVENT, class EVENT_TIMEOUT, class EVENT_ERR, class FUT>
225 CancellationToken token;
226 rep_future.then([&, token](FUT res) {
227 if (token.IsCancelled()) {
228 return;
229 }
230 try {
231 if (res.has_value()) {
232 // NOLINTNEXTLINE
233 if constexpr (std::is_void<typename FUT::value_type>::value) {
234 LOG4CPLUS_DEBUG(GetLogger(),
235 "Received async VOID reply, triggering associated event <"
236 << typeid(EVENT).name() << ">");
237 sm.PostEvent(std::make_unique<EVENT>());
238 } else {
239 // LOG4CPLUS_DEBUG(GetLogger(), "Received async reply <" << res.get() << ">,
240 // triggering associated event <" << typeid(EVENT).name() << ">");
241 LOG4CPLUS_DEBUG(GetLogger(),
242 "Received async reply, triggering associated event <"
243 << typeid(EVENT).name() << ">");
244 sm.PostEvent(std::make_unique<EVENT>(res.get()));
245 }
246 LOG4CPLUS_DEBUG(GetLogger(),
247 "Received async reply, triggering associated event - done!");
248 } else if (res.has_exception()) {
249 LOG4CPLUS_DEBUG(GetLogger(), "Received exception as reply, rethrowing it.");
250 boost::rethrow_exception(res.get_exception_ptr());
251 } else {
252 RAD_ASSERTNEVER();
253 }
254 } catch (const elt::mal::TimeoutException& e) {
255 LOG4CPLUS_DEBUG(GetLogger(), "ExceptionTimeout while waiting for reply");
256 sm.PostEvent(std::make_unique<EVENT_TIMEOUT>());
257 } catch (...) {
258 LOG4CPLUS_DEBUG(GetLogger(), "Received exception as reply, post associated event <"
259 << typeid(EVENT).name() << ">");
260 sm.PostEvent(std::make_unique<EVENT_ERR>(res.get_exception_ptr()));
261 }
262 });
263 LOG4CPLUS_DEBUG(GetLogger(), "Installed future continuation");
264 return token;
265}
266
267} // namespace cii
268} // namespace rad
269
270#endif // RAD_MAL_REQUESTOR_HPP_
Definition smAdapter.hpp:60
void PostEvent(SharedEvent e)
Definition smAdapter.cpp:296
Definition utils.hpp:66
bool IsCancelled() const
Definition utils.hpp:89
Definition requestor.hpp:42
Requestor(const elt::mal::Uri &uri, const std::vector< std::shared_ptr< elt::mal::rr::qos::QoS > > &qos, const std::optional< elt::mal::Mal::Properties > mal_properties={})
Definition requestor.hpp:52
std::shared_ptr< INTERFACE_TYPE > & GetInterface()
Definition requestor.hpp:80
Requestor(const Requestor &)=delete
Requestor & operator=(const Requestor &)=delete
Requestor(const elt::mal::Uri &uri, const std::optional< elt::mal::Mal::Properties > mal_properties={})
Definition requestor.hpp:69
Logger class.
#define RAD_TRACE(logger)
Definition logger.hpp:21
Utils class header file.
CancellationToken RouteReplyWithTimeout(FUT &&rep_future, rad::SMAdapter &sm)
Definition requestor.hpp:224
void RoutePartialReply(std::shared_ptr<::elt::mal::rr::Ami< T > > ami, rad::SMAdapter &sm)
Definition requestor.hpp:104
CancellationToken RouteReply(FUT &&rep_future, rad::SMAdapter &sm)
Definition requestor.hpp:138
Definition actionsApp.cpp:23
const std::string LOGGER_NAME
Definition logger.hpp:76
log4cplus::Logger & GetLogger()
Definition logger.cpp:72
SMAdapter class header file.