DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
CommandFacility.cpp
Go to the documentation of this file.
1
9#include "cmdlib/Issues.hpp"
10#include "logging/Logging.hpp"
11
12#include <future>
13#include <functional>
14#include <utility>
15#include <atomic>
16#include <chrono>
17#include <string>
18
19using namespace dunedaq::cmdlib;
20
22{
23 if (m_active.load()) {
24 m_active.store(false);
25 if(m_executor.joinable()) {
26 m_executor.join();
27 }
28 }
29}
30
31void
32CommandFacility::set_commanded(CommandedObject& commanded, std::string name)
33{
34 if (m_commanded_object == nullptr) {
35 m_name = name;
36 m_commanded_object = &commanded;
37 m_command_callback = std::bind(&CommandFacility::handle_command, this, std::placeholders::_1, std::placeholders::_2);
38 m_active.store(true);
39 m_executor = std::thread(&CommandFacility::executor, this);
40 } else {
41 ers::error(CommandFacilityInitialization(ERS_HERE, "set_commanded shall be called once."));
42 }
43}
44
45void
47{
48 auto execfut = std::async(std::launch::deferred, m_command_callback, std::move(cmd), std::move(meta));
49 m_completion_queue.push(std::move(execfut));
50}
51
52void
54{
55 try {
57 meta.success = true;
58 meta.result = "OK";
59 meta.appname = m_name;
60 } catch (const ers::Issue& ei ) {
61 meta.success = false;
62 meta.result = ei.what();
63 meta.appname = m_name;
64 ers::error(CommandExecutionFailed(ERS_HERE, "Caught ers::Issue", ei));
65 } catch (const std::exception& exc) {
66 meta.success = false;
67 meta.result = exc.what();
68 meta.appname = m_name;
69 ers::error(CommandExecutionFailed(ERS_HERE, "Caught std::exception", exc));
70 } catch (...) { // NOLINT JCF Jan-27-2021 violates letter of the law but not the spirit
71 meta.success = false;
72 meta.result = "Caught unknown exception";
73 meta.appname = m_name;
75 }
76 completion_callback(cmd, meta);
77}
78
79void
81{
82 std::future<void> fut;
83 while (m_active.load()) {
84 if (m_completion_queue.empty()) {
85 std::this_thread::sleep_for(std::chrono::milliseconds(10));
86 } else {
87 bool success = m_completion_queue.try_pop(fut);
88 if (!success) {
89 ers::error(CompletionQueueIssue(ERS_HERE, "Can't get from completion queue."));
90 } else {
91 fut.wait(); // trigger execution
92 }
93 }
94 }
95}
#define ERS_HERE
void handle_command(const cmdobj_t &cmd, cmd::CommandReply meta)
The glue between commanded and completion callback.
virtual void completion_callback(const cmdobj_t &cmd, cmd::CommandReply &meta)=0
Must be implemented to handling the results of the commands.
CommandedObject * m_commanded_object
Commanded Object to run execute with received commands as parameters.
std::string m_name
name of the commanded object
std::atomic< bool > m_active
Single thrad is responsible to trigger tasks.
void set_commanded(CommandedObject &commanded, std::string name)
Meant to be called once from main.
void execute_command(const cmdobj_t &cmd, cmd::CommandReply meta)
Feed commands from the implementation.
Interface needed by commanded objects in the DAQ.
virtual void execute(const cmdobj_t &command)=0
Pure virtual execute member.
Base class for any user define issue.
Definition Issue.hpp:69
const char * what() const noexcept
General cause of the issue.
Definition Issue.hpp:133
Unsupported std::string uri CommandExecutionFailed
Definition Issues.hpp:68
void error(const Issue &issue)
Definition ers.hpp:81