RTC Toolkit 4.0.1
Loading...
Searching...
No Matches
optimisable.hpp
Go to the documentation of this file.
1
13#ifndef RTCTK_COMPONENTFRAMEWORK_OPTIMISABLE_HPP
14#define RTCTK_COMPONENTFRAMEWORK_OPTIMISABLE_HPP
15
22
24namespace detail {
36public:
43 explicit OptimiseContext(rad::cii::Request<std::string, std::string> const& request)
44 : m_logger(GetLogger("rtctk")), m_request(request), m_arg() {
45 m_arg = JsonPayload::parse(m_request.GetRequestPayload());
46 }
47 OptimiseContext(OptimiseContext&&) noexcept = default;
48
52 JsonPayload const& GetArg() const noexcept {
53 return m_arg;
54 }
55
61 void SendReply() noexcept {
62 try {
63 m_request.SetReplyValue(STD_OK_REPLY);
64 } catch (std::exception const& exception) {
65 LOG4CPLUS_ERROR(
66 m_logger, "OptimiseContext::SendReply: Failed to send reply: " << exception.what());
67 } catch (...) {
68 LOG4CPLUS_ERROR(
69 m_logger,
70 "OptimiseContext::SendReply: Failed to send reply with unknown exception.");
71 }
72 }
73
79 void SendErrorReply(std::exception_ptr eptr) noexcept {
80 try {
81 m_request.SetException(RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
82 } catch (...) {
83 }
84 }
85
86private:
87 log4cplus::Logger& m_logger;
88
90 rad::cii::Request<std::string, std::string> m_request;
94 JsonPayload m_arg;
95};
96} // namespace detail
97
127template <typename Super>
128struct Optimisable : Super {
129 static_assert(std::is_base_of_v<RtcComponent, Super>, "'Optimisable' requires 'RtcComponent'");
130
135 class BizLogicIf : public Super::BizLogicIf {
136 public:
147 virtual void ActivityOptimising(StopToken st, JsonPayload const& arg) {
148 }
158 virtual bool GuardOptimisingAllowed(JsonPayload const& arg) {
159 return true;
160 }
161 };
162
166 class InputStage : public Super::InputStage {
167 public:
168 using Super::InputStage::InputStage;
169
170 void Start() override {
171 Super::InputStage::Start();
172
173 OptCmdsImpl::Register(this->m_replier, this->m_engine);
174 }
175 };
176
180 class OutputStage : public Super::OutputStage {
181 public:
182 OutputStage(StateMachineEngine& engine, BizLogicIf& bl) : Super::OutputStage(engine, bl) {
183 // Handlers ###################################################################
184
185 engine.RegisterRejectHandler<events::Optimise, RequestRejected>();
186
188 this->m_engine.PostEvent(std::make_unique<events::OptimiseDone>());
189 };
190
191 m_optimise_error_handler = [this](std::exception_ptr eptr) {
192 this->m_engine.PostEvent(std::make_unique<events::OptimiseError>(std::move(eptr)));
193 };
194
195 // No Disable in states ###############################################################
196
197 this->m_no_disable_in_states.push_back("On::Operational:Optimise:Busy");
198
199 // No Update in states ################################################################
200
201 this->m_no_update_in_states.push_back("On::Operational:Optimise:Busy");
202
203 // No Optimise in states ##############################################################
204
205 this->m_no_optimise_in_states.push_back("On:Update:Busy");
206
207 // Guards #####################################################################
208
209 engine.RegisterGuardStatic<events::Optimise>(
210 "GuardOptimisingAllowed", [this](events::Optimise const& ev) -> bool {
219 auto act_state = this->m_engine.GetState();
220 for (auto& s : m_no_optimise_in_states) {
221 if (act_state.find(s) != std::string::npos) {
222 return false;
223 }
224 }
225 detail::OptimiseContext ctx(ev.GetPayload());
226 if (static_cast<BizLogicIf&>(this->m_logic)
227 .GuardOptimisingAllowed(ctx.GetArg())) {
228 // Optimise is allowed so context is stored.
229 // If there's an active context (and correspondingly an active
230 // request being processed something have gone terribly wrong)
231 assert(!m_optimise_ctx);
232 m_optimise_ctx.emplace(std::move(ctx));
233 return true;
234 }
235 return false;
236 });
237
238 // Activities #####################################################################
239
240 engine.RegisterActivity(
241 "ActivityOptimising",
242 [this](StopToken stop_token) {
243 assert(m_optimise_ctx);
244 static_cast<BizLogicIf&>(this->m_logic)
245 .ActivityOptimising(stop_token, m_optimise_ctx->GetArg());
246 },
249
250 // Actions #####################################################################
251 engine.RegisterActionStatic<events::OptimiseDone>("ActionOptimisingDone",
252 [this](events::OptimiseDone const&) {
253 assert(m_optimise_ctx);
254 m_optimise_ctx->SendReply();
255 m_optimise_ctx.reset();
256 });
257
258 engine.RegisterActionStatic<events::OptimiseError>(
259 "ActionOptimisingFailed", [this](events::OptimiseError const& ev) {
260 m_optimise_ctx->SendErrorReply(ev.GetPayload());
261 m_optimise_ctx.reset();
262 });
263 }
264
265 protected:
266 std::optional<detail::OptimiseContext> m_optimise_ctx;
267 std::function<void()> m_optimise_success_handler;
268 std::function<void(std::exception_ptr)> m_optimise_error_handler;
269 std::list<std::string> m_no_optimise_in_states;
270 };
271
275 class ModelBuilder : public Super::ModelBuilder {
276 public:
277 explicit ModelBuilder(StateMachineEngine& engine) : Super::ModelBuilder(engine) {
278 // clang-format off
279 this->mm.ModStateType("On::Operational", Parallel);
280
281 this->mm.AddState(Composite, "On::Operational:Optimise:", "On::Operational");
282 this->mm.AddState(Initial, "On::Operational:Optimise:Initial", "On::Operational:Optimise:");
283 this->mm.AddState(Simple, "On::Operational:Optimise:Idle", "On::Operational:Optimise:");
284 this->mm.AddState(Simple, "On::Operational:Optimise:Busy", "On::Operational:Optimise:", "ActivityOptimising");
285
286 this->mm.AddTrans("On::Operational:Optimise:Initial" , "On::Operational:Optimise:Idle" );
287 this->mm.AddTrans("On::Operational:Optimise:Idle" , "On::Operational:Optimise:Busy", events::Optimise::ID, "GuardOptimisingAllowed");
288 this->mm.AddTrans("On::Operational:Optimise:Busy" , "On::Operational:Optimise:Idle", events::OptimiseDone::ID, "", "ActionOptimisingDone");
289 this->mm.AddTrans("On::Operational:Optimise:Busy" , "On::Operational:Optimise:Idle", events::OptimiseError::ID, "", "ActionOptimisingFailed");
290 // clang-format on
291 }
292 };
293};
294
295} // namespace rtctk::componentFramework
296
297#endif
Adapter object intended to be used in contexts without direct access to the output-stream object.
Definition: exceptions.hpp:185
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition: optCmdsImpl.hpp:37
Business logic interface for Optimisable mixin.
Definition: optimisable.hpp:135
virtual bool GuardOptimisingAllowed(JsonPayload const &arg)
Determines if optimising is possible at this time with the provided argument.
Definition: optimisable.hpp:158
virtual void ActivityOptimising(StopToken st, JsonPayload const &arg)
Activity executed in its own thread that performs the requested optimization.
Definition: optimisable.hpp:147
void Start() override
Definition: optimisable.hpp:170
ModelBuilder(StateMachineEngine &engine)
Definition: optimisable.hpp:277
std::optional< detail::OptimiseContext > m_optimise_ctx
Definition: optimisable.hpp:266
OutputStage(StateMachineEngine &engine, BizLogicIf &bl)
Definition: optimisable.hpp:182
std::function< void()> m_optimise_success_handler
Definition: optimisable.hpp:267
std::function< void(std::exception_ptr)> m_optimise_error_handler
Definition: optimisable.hpp:268
std::list< std::string > m_no_optimise_in_states
Definition: optimisable.hpp:269
Thrown if the command was accepted but the task to run failed.
Definition: rtcComponent.hpp:53
Thrown if a command is not allowed in current state or guard.
Definition: rtcComponent.hpp:40
Definition: stateMachineEngine.hpp:35
void RegisterRejectHandler(std::string const &id, RejectMethod reject)
Register reject handler.
Definition: stateMachineEngine.cpp:131
void RegisterActivity(std::string const &id, ActivityMethod activity, SuccessMethod on_success, FailureMethod on_failure)
Register activity.
Definition: stateMachineEngine.cpp:123
void RegisterGuardStatic(std::string const &id, std::function< bool(Event const &)> guard)
Register guard for statically known event type.
Definition: stateMachineEngine.hpp:126
void RegisterActionStatic(std::string const &id, std::function< void(Event const &)> action)
Register action for statically known event type.
Definition: stateMachineEngine.hpp:93
Holds context necessary for processing a optimise request to completion.
Definition: optimisable.hpp:35
OptimiseContext(rad::cii::Request< std::string, std::string > const &request)
Construct context with provided request.
Definition: optimisable.hpp:43
void SendErrorReply(std::exception_ptr eptr) noexcept
Send exceptional reply.
Definition: optimisable.hpp:79
OptimiseContext(OptimiseContext &&) noexcept=default
void SendReply() noexcept
Sends hardcoded string reply.
Definition: optimisable.hpp:61
JsonPayload const & GetArg() const noexcept
Definition: optimisable.hpp:52
Provides macros and utilities for exception handling.
log4cplus::Logger & GetLogger(const std::string &name="app")
Get handle to a specific logger.
Definition: logger.cpp:180
Defines the JSON payload type JsonPayload.
Logging Support Library based on log4cplus.
Definition: commandReplier.cpp:22
const std::string STD_OK_REPLY
Definition: stdComponent.hpp:86
nlohmann::json JsonPayload
Type requirements:
Definition: jsonPayload.hpp:25
rad::StopToken StopToken
Definition: stopToken.hpp:20
@ Simple
Definition: model.hpp:22
@ Composite
Definition: model.hpp:22
@ Parallel
Definition: model.hpp:22
@ Initial
Definition: model.hpp:22
Implementation of MAL commands for layer 'Optimisable'.
Lifecycle of a basic 'RtcComponent'.
A simple Stop Token.
Life cycle extension to make RtcComponent Optimisable.
Definition: optimisable.hpp:128