Line data Source code
1 :
2 : /**
3 : * @file Application.cpp Application implementataion
4 : *
5 : * This is part of the DUNE DAQ Application Framework, copyright 2020.
6 : * Licensing/copyright details are in the COPYING file that you should have
7 : * received with this code.
8 : */
9 :
10 : #include "Application.hpp"
11 :
12 : #include "appfwk/cmd/Nljs.hpp"
13 : #include "appfwk/opmon/application.pb.h"
14 :
15 : #include "confmodel/Application.hpp"
16 : #include "confmodel/OpMonURI.hpp"
17 : #include "confmodel/Session.hpp"
18 : #include "logging/Logging.hpp"
19 : #include "rcif/cmd/Nljs.hpp"
20 :
21 : #include <string>
22 : #include <unistd.h>
23 : #include <utility>
24 :
25 : namespace dunedaq::appfwk {
26 :
27 11 : Application::Application(std::string app_name,
28 : std::string session_name,
29 : std::string cmdlibimpl,
30 : std::string confimpl,
31 11 : std::string configuration_id)
32 : : ConfigurationManagerOwner(confimpl, app_name, configuration_id)
33 20 : , OpMonManager(session_name, app_name, get_config_manager()->get_session()->get_opmon_uri()->get_URI(app_name))
34 : , NamedObject(app_name)
35 10 : , m_mod_mgr(session_name)
36 10 : , m_state("NONE")
37 10 : , m_busy(false)
38 10 : , m_error(false)
39 43 : , m_initialized(false)
40 : {
41 10 : m_runinfo.set_running(false);
42 10 : m_runinfo.set_run_number(0);
43 10 : m_runinfo.set_run_time(0);
44 :
45 10 : m_cmd_fac = cmdlib::make_command_facility(
46 20 : cmdlibimpl, session_name, get_config_manager()->get_session()->get_connectivity_service());
47 :
48 10 : set_opmon_conf(get_config_manager()->get_application()->get_opmon_conf());
49 :
50 18 : TLOG() << "confimpl=<" << confimpl << ">\n";
51 17 : }
52 :
53 : void
54 6 : Application::init()
55 : {
56 6 : m_cmd_fac->set_commanded(*this, get_name());
57 6 : m_mod_mgr.initialize(get_config_manager(), *this);
58 6 : set_state("INITIAL");
59 6 : m_initialized = true;
60 6 : }
61 :
62 : void
63 2 : Application::run(std::atomic<bool>& end_marker)
64 : {
65 2 : if (!m_initialized) {
66 1 : throw ApplicationNotInitialized(ERS_HERE, get_name());
67 : }
68 :
69 1 : start_monitoring();
70 1 : m_cmd_fac->run(end_marker);
71 :
72 1 : m_mod_mgr.cleanup();
73 :
74 1 : stop_monitoring();
75 1 : }
76 :
77 : void
78 7 : Application::execute(const dataobj_t& cmd_data)
79 : {
80 7 : auto rc_cmd = cmd_data.get<rcif::cmd::RCCommand>();
81 7 : std::string cmdname = rc_cmd.id;
82 7 : if (!check_state_for_cmd(cmd_data)) {
83 1 : throw InvalidStateForCommand(ERS_HERE, cmdname, get_state(), m_error.load(), m_busy.load());
84 : }
85 :
86 6 : m_busy.store(true);
87 :
88 6 : if (cmdname == "start") {
89 3 : auto cmd_obj = rc_cmd.data.get<cmd::CmdObj>();
90 :
91 3 : for (const auto& addressed : cmd_obj.modules) {
92 2 : dataobj_t startpars = addressed.data;
93 2 : auto rc_startpars = startpars.get<rcif::cmd::StartParams>();
94 2 : m_runinfo.set_run_number(rc_startpars.run);
95 2 : break;
96 2 : }
97 :
98 3 : m_run_start_time = std::chrono::steady_clock::now();
99 3 : m_runinfo.set_running(true);
100 3 : m_runinfo.set_run_time(0);
101 6 : } else if (cmdname == "stop") {
102 1 : m_run_start_time = std::chrono::steady_clock::time_point();
103 1 : m_runinfo.set_running(false);
104 1 : m_runinfo.set_run_number(0);
105 1 : m_runinfo.set_run_time(0);
106 : }
107 :
108 6 : try {
109 6 : m_mod_mgr.execute(cmdname, static_cast<DAQModule::CommandData_t>(rc_cmd.data));
110 4 : m_busy.store(false);
111 4 : if (rc_cmd.exit_state != "ANY")
112 3 : set_state(rc_cmd.exit_state);
113 2 : } catch (ers::Issue& ex) {
114 2 : m_busy.store(false);
115 2 : m_error.store(true);
116 2 : throw;
117 2 : }
118 :
119 4 : publish_app_info();
120 10 : }
121 :
122 : void
123 0 : Application::generate_opmon_data()
124 : {
125 0 : publish_app_info();
126 0 : }
127 :
128 : bool
129 14 : Application::check_state_for_cmd(const dataobj_t& cmd_data) const
130 : {
131 14 : if (m_busy.load() || m_error.load())
132 1 : return false;
133 :
134 13 : std::string entry_state = cmd_data.get<rcif::cmd::RCCommand>().entry_state;
135 13 : if (entry_state == "ANY" || get_state() == entry_state)
136 : return true;
137 :
138 : return false;
139 13 : }
140 :
141 : void
142 4 : Application::publish_app_info() {
143 :
144 4 : opmon::AppInfo ai;
145 8 : ai.set_state(get_state());
146 4 : ai.set_busy(m_busy.load());
147 4 : ai.set_error(m_error.load());
148 :
149 4 : char hostname[256]; // NOLINT
150 4 : auto res = gethostname(hostname, 256);
151 4 : if (res < 0)
152 0 : ai.set_host("Unknown");
153 : else
154 8 : ai.set_host(std::string(hostname));
155 :
156 4 : publish(std::move(ai), {}, opmonlib::to_level(opmonlib::EntryOpMonLevel::kTopPriority));
157 :
158 4 : if (m_run_start_time.time_since_epoch().count() != 0) {
159 2 : auto now = std::chrono::steady_clock::now();
160 2 : m_runinfo.set_run_time(std::chrono::duration_cast<std::chrono::seconds>(now - m_run_start_time).count());
161 : }
162 :
163 4 : publish(decltype(m_runinfo)(m_runinfo));
164 :
165 4 : }
166 :
167 :
168 : } // namespace dunedaq::appfwk
|