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 1 : }
74 :
75 : void
76 7 : Application::execute(const dataobj_t& cmd_data)
77 : {
78 7 : auto rc_cmd = cmd_data.get<rcif::cmd::RCCommand>();
79 7 : std::string cmdname = rc_cmd.id;
80 7 : if (!check_state_for_cmd(cmd_data)) {
81 1 : throw InvalidStateForCommand(ERS_HERE, cmdname, get_state(), m_error.load(), m_busy.load());
82 : }
83 :
84 6 : m_busy.store(true);
85 :
86 6 : if (cmdname == "start") {
87 3 : auto cmd_obj = rc_cmd.data.get<cmd::CmdObj>();
88 :
89 3 : for (const auto& addressed : cmd_obj.modules) {
90 2 : dataobj_t startpars = addressed.data;
91 2 : auto rc_startpars = startpars.get<rcif::cmd::StartParams>();
92 2 : m_runinfo.set_run_number(rc_startpars.run);
93 2 : break;
94 2 : }
95 :
96 3 : m_run_start_time = std::chrono::steady_clock::now();
97 3 : m_runinfo.set_running(true);
98 3 : m_runinfo.set_run_time(0);
99 6 : } else if (cmdname == "stop") {
100 1 : m_run_start_time = std::chrono::steady_clock::time_point();
101 1 : m_runinfo.set_running(false);
102 1 : m_runinfo.set_run_number(0);
103 1 : m_runinfo.set_run_time(0);
104 : }
105 :
106 6 : try {
107 6 : m_mod_mgr.execute(cmdname, static_cast<DAQModule::CommandData_t>(rc_cmd.data));
108 4 : m_busy.store(false);
109 4 : if (rc_cmd.exit_state != "ANY")
110 3 : set_state(rc_cmd.exit_state);
111 2 : } catch (ers::Issue& ex) {
112 2 : m_busy.store(false);
113 2 : m_error.store(true);
114 2 : throw;
115 2 : }
116 :
117 4 : publish_app_info();
118 10 : }
119 :
120 : void
121 0 : Application::generate_opmon_data()
122 : {
123 0 : publish_app_info();
124 0 : }
125 :
126 : bool
127 14 : Application::check_state_for_cmd(const dataobj_t& cmd_data) const
128 : {
129 14 : if (m_busy.load() || m_error.load())
130 1 : return false;
131 :
132 13 : std::string entry_state = cmd_data.get<rcif::cmd::RCCommand>().entry_state;
133 13 : if (entry_state == "ANY" || get_state() == entry_state)
134 : return true;
135 :
136 : return false;
137 13 : }
138 :
139 : void
140 4 : Application::publish_app_info() {
141 :
142 4 : opmon::AppInfo ai;
143 8 : ai.set_state(get_state());
144 4 : ai.set_busy(m_busy.load());
145 4 : ai.set_error(m_error.load());
146 :
147 4 : char hostname[256]; // NOLINT
148 4 : auto res = gethostname(hostname, 256);
149 4 : if (res < 0)
150 0 : ai.set_host("Unknown");
151 : else
152 8 : ai.set_host(std::string(hostname));
153 :
154 4 : publish(std::move(ai), {}, opmonlib::to_level(opmonlib::EntryOpMonLevel::kTopPriority));
155 :
156 4 : if (m_run_start_time.time_since_epoch().count() != 0) {
157 2 : auto now = std::chrono::steady_clock::now();
158 2 : m_runinfo.set_run_time(std::chrono::duration_cast<std::chrono::seconds>(now - m_run_start_time).count());
159 : }
160 :
161 4 : publish(decltype(m_runinfo)(m_runinfo));
162 :
163 4 : }
164 :
165 :
166 : } // namespace dunedaq::appfwk
|