Line data Source code
1 : #include "TRACE/tracemf.h"
2 : #include "artdaq/DAQdata/Globals.hh"
3 : #define TRACE_NAME "RoutingManagerApp"
4 :
5 : #include "artdaq/Application/RoutingManagerApp.hh"
6 :
7 : #include <boost/bind.hpp>
8 : #include <boost/exception/all.hpp>
9 : #include <boost/lexical_cast.hpp>
10 : #include <boost/thread.hpp>
11 :
12 : #include <memory>
13 :
14 : /**
15 : * Default constructor.
16 : */
17 0 : artdaq::RoutingManagerApp::RoutingManagerApp() = default;
18 :
19 : // *******************************************************************
20 : // *** The following methods implement the state machine operations.
21 : // *******************************************************************
22 :
23 0 : bool artdaq::RoutingManagerApp::do_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
24 : {
25 0 : report_string_ = "";
26 0 : external_request_status_ = true;
27 :
28 : // in the following block, we first destroy the existing RoutingManager
29 : // instance, then create a new one. Doing it in one step does not
30 : // produce the desired result since that creates a new instance and
31 : // then deletes the old one, and we need the opposite order.
32 0 : routing_manager_ptr_.reset(nullptr);
33 0 : routing_manager_ptr_ = std::make_unique<RoutingManagerCore>();
34 0 : external_request_status_ = routing_manager_ptr_->initialize(pset, timeout, timestamp);
35 0 : if (!external_request_status_)
36 : {
37 0 : report_string_ = "Error initializing ";
38 0 : report_string_.append(app_name + " ");
39 0 : report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
40 : }
41 :
42 0 : return external_request_status_;
43 : }
44 :
45 0 : bool artdaq::RoutingManagerApp::do_start(art::RunID id, uint64_t timeout, uint64_t timestamp)
46 : {
47 0 : report_string_ = "";
48 0 : external_request_status_ = routing_manager_ptr_->start(id, timeout, timestamp);
49 0 : if (!external_request_status_)
50 : {
51 0 : report_string_ = "Error starting ";
52 0 : report_string_.append(app_name + " ");
53 0 : report_string_.append("for run number ");
54 0 : report_string_.append(boost::lexical_cast<std::string>(id.run()));
55 0 : report_string_.append(", timeout ");
56 0 : report_string_.append(boost::lexical_cast<std::string>(timeout));
57 0 : report_string_.append(", timestamp ");
58 0 : report_string_.append(boost::lexical_cast<std::string>(timestamp));
59 0 : report_string_.append(".");
60 : }
61 :
62 0 : boost::thread::attributes attrs;
63 0 : attrs.set_stack_size(4096 * 2000); // 8 MB
64 : try
65 : {
66 0 : routing_manager_thread_ = boost::thread(attrs, boost::bind(&RoutingManagerCore::process_event_table, routing_manager_ptr_.get()));
67 : char tname[16]; // Size 16 - see man page pthread_setname_np(3) and/or prctl(2)
68 0 : snprintf(tname, sizeof(tname) - 1, "%d-Routing", my_rank); // NOLINT
69 0 : tname[sizeof(tname) - 1] = '\0'; // assure term. snprintf is not too evil :)
70 0 : auto handle = routing_manager_thread_.native_handle();
71 0 : pthread_setname_np(handle, tname);
72 : }
73 0 : catch (const boost::exception& e)
74 : {
75 0 : TLOG(TLVL_ERROR) << "Caught boost::exception starting RoutingManagerCore thread: " << boost::diagnostic_information(e) << ", errno=" << errno;
76 0 : std::cerr << "Caught boost::exception starting RoutingManagerCore thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
77 0 : exit(5);
78 0 : }
79 :
80 0 : return external_request_status_;
81 0 : }
82 :
83 0 : bool artdaq::RoutingManagerApp::do_stop(uint64_t timeout, uint64_t timestamp)
84 : {
85 0 : report_string_ = "";
86 0 : external_request_status_ = routing_manager_ptr_->stop(timeout, timestamp);
87 0 : if (!external_request_status_)
88 : {
89 0 : report_string_ = "Error stopping ";
90 0 : report_string_.append(app_name + ".");
91 0 : return false;
92 : }
93 :
94 0 : if (routing_manager_thread_.joinable())
95 : {
96 0 : routing_manager_thread_.join();
97 : }
98 :
99 0 : TLOG(TLVL_DEBUG + 32, app_name + "App") << "do_stop(uint64_t, uint64_t): "
100 0 : << "Number of table entries sent = " << routing_manager_ptr_->get_update_count()
101 0 : << ".";
102 :
103 0 : return external_request_status_;
104 : }
105 :
106 0 : bool artdaq::RoutingManagerApp::do_pause(uint64_t timeout, uint64_t timestamp)
107 : {
108 0 : report_string_ = "";
109 0 : external_request_status_ = routing_manager_ptr_->pause(timeout, timestamp);
110 0 : if (!external_request_status_)
111 : {
112 0 : report_string_ = "Error pausing ";
113 0 : report_string_.append(app_name + ".");
114 : }
115 0 : if (routing_manager_thread_.joinable())
116 : {
117 0 : routing_manager_thread_.join();
118 : }
119 :
120 0 : TLOG(TLVL_DEBUG + 32, app_name + "App") << "do_pause(uint64_t, uint64_t): "
121 0 : << "Number of table entries sent = " << routing_manager_ptr_->get_update_count()
122 0 : << ".";
123 :
124 0 : return external_request_status_;
125 : }
126 :
127 0 : bool artdaq::RoutingManagerApp::do_resume(uint64_t timeout, uint64_t timestamp)
128 : {
129 0 : report_string_ = "";
130 0 : external_request_status_ = routing_manager_ptr_->resume(timeout, timestamp);
131 0 : if (!external_request_status_)
132 : {
133 0 : report_string_ = "Error resuming ";
134 0 : report_string_.append(app_name + ".");
135 : }
136 :
137 0 : boost::thread::attributes attrs;
138 0 : attrs.set_stack_size(4096 * 2000); // 8000 KB
139 :
140 0 : TLOG(TLVL_INFO) << "Starting Routing Manager thread";
141 : try
142 : {
143 0 : routing_manager_thread_ = boost::thread(attrs, boost::bind(&RoutingManagerCore::process_event_table, routing_manager_ptr_.get()));
144 : char tname[16]; // Size 16 - see man page pthread_setname_np(3) and/or prctl(2)
145 0 : snprintf(tname, sizeof(tname) - 1, "%d-Routing", my_rank); // NOLINT
146 0 : tname[sizeof(tname) - 1] = '\0'; // assure term. snprintf is not too evil :)
147 0 : auto handle = routing_manager_thread_.native_handle();
148 0 : pthread_setname_np(handle, tname);
149 : }
150 0 : catch (boost::exception const& e)
151 : {
152 0 : TLOG(TLVL_ERROR) << "Exception encountered starting Routing Manager thread: " << boost::diagnostic_information(e) << ", errno=" << errno;
153 0 : std::cerr << "Exception encountered starting Routing Manager thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
154 0 : exit(3);
155 0 : }
156 0 : TLOG(TLVL_INFO) << "Started Routing Manager thread";
157 :
158 0 : return external_request_status_;
159 0 : }
160 :
161 0 : bool artdaq::RoutingManagerApp::do_shutdown(uint64_t timeout)
162 : {
163 0 : report_string_ = "";
164 0 : external_request_status_ = routing_manager_ptr_->shutdown(timeout);
165 0 : if (!external_request_status_)
166 : {
167 0 : report_string_ = "Error shutting down ";
168 0 : report_string_.append(app_name + ".");
169 : }
170 0 : return external_request_status_;
171 : }
172 :
173 0 : bool artdaq::RoutingManagerApp::do_soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
174 : {
175 0 : report_string_ = "";
176 0 : external_request_status_ = routing_manager_ptr_->soft_initialize(pset, timeout, timestamp);
177 0 : if (!external_request_status_)
178 : {
179 0 : report_string_ = "Error soft-initializing ";
180 0 : report_string_.append(app_name + " ");
181 0 : report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
182 : }
183 0 : return external_request_status_;
184 : }
185 :
186 0 : bool artdaq::RoutingManagerApp::do_reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
187 : {
188 0 : external_request_status_ = routing_manager_ptr_->reinitialize(pset, timeout, timestamp);
189 0 : if (!external_request_status_)
190 : {
191 0 : report_string_ = "Error reinitializing ";
192 0 : report_string_.append(app_name + " ");
193 0 : report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
194 : }
195 0 : return external_request_status_;
196 : }
197 :
198 0 : void artdaq::RoutingManagerApp::BootedEnter()
199 : {
200 0 : TLOG(TLVL_DEBUG + 32, app_name + "App") << "Booted state entry action called.";
201 :
202 : // the destruction of any existing RoutingManagerCore has to happen in the
203 : // Booted Entry action rather than the Initialized Exit action because the
204 : // Initialized Exit action is only called after the "init" transition guard
205 : // condition is executed.
206 0 : routing_manager_ptr_.reset(nullptr);
207 0 : }
208 :
209 0 : std::string artdaq::RoutingManagerApp::report(std::string const& which) const
210 : {
211 0 : std::string resultString;
212 :
213 : // if all that is requested is the latest state change result, return it
214 0 : if (which == "transition_status")
215 : {
216 0 : if (report_string_.length() > 0) { return report_string_; }
217 :
218 0 : return "Success";
219 : }
220 :
221 : //// if there is an outstanding report/message at the Commandable/Application
222 : //// level, prepend that
223 : // if (report_string_.length() > 0) {
224 : // resultString.append("*** Overall status message:\r\n");
225 : // resultString.append(report_string_ + "\r\n");
226 : // resultString.append("*** Requested report response:\r\n");
227 : // }
228 :
229 : // pass the request to the RoutingManagerCore instance, if it's available
230 0 : if (routing_manager_ptr_ != nullptr)
231 : {
232 0 : resultString.append(routing_manager_ptr_->report(which));
233 : }
234 : else
235 : {
236 0 : resultString.append("This RoutingManager has not yet been initialized and ");
237 0 : resultString.append("therefore can not provide reporting.");
238 : }
239 :
240 0 : return resultString;
241 0 : }
|