artdaq  v3_01_00
Commandable.cc
1 
2 #define TRACE_NAME (app_name + "_CommandableInterface").c_str()
3 
4 #include "artdaq/Application/Commandable.hh"
5 #include "artdaq/DAQdata/Globals.hh"
6 
7 // ELF 3/22/18:
8 // We may want to separate these onto different levels later,
9 // but I think the TRACE_NAME separation is enough for now...
10 #define TLVL_INIT TLVL_TRACE
11 #define TLVL_STOP TLVL_TRACE
12 #define TLVL_STATUS TLVL_TRACE
13 #define TLVL_START TLVL_TRACE
14 #define TLVL_PAUSE TLVL_TRACE
15 #define TLVL_RESUME TLVL_TRACE
16 #define TLVL_SHUTDOWN TLVL_TRACE
17 #define TLVL_SOFT_INIT TLVL_TRACE
18 #define TLVL_REINIT TLVL_TRACE
19 #define TLVL_INRUN_FAILURE TLVL_TRACE
20 #define TLVL_LEGAL_COMMANDS TLVL_TRACE
21 
23 , primary_mutex_() {}
24 
25 // **********************************************************************
26 // *** The following methods implement the externally available commands.
27 // **********************************************************************
28 
29 bool artdaq::Commandable::initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
30 {
31  std::lock_guard<std::mutex> lk(primary_mutex_);
32  external_request_status_ = true;
33  report_string_ = "All is OK.";
34 
35 #if ART_HEX_VERSION >= 0x21100
36  SetMFModuleName("Initializing");
37 #endif
38 
39  TLOG(TLVL_INIT) << "Initialize transition started";
40  auto start_time = std::chrono::steady_clock::now();
41  std::string initialState = fsm_.getState().getName();
42  fsm_.init(pset, timeout, timestamp);
43  if (external_request_status_)
44  {
45  std::string finalState = fsm_.getState().getName();
46 #if ART_HEX_VERSION >= 0x21100
47  SetMFModuleName(finalState);
48 #endif
49  TLOG(TLVL_DEBUG)
50  << "States before and after an init transition: "
51  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
52  }
53  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
54 
55  TLOG(TLVL_INIT) << "Initialize transition complete";
56  return (external_request_status_);
57 }
58 
59 bool artdaq::Commandable::start(art::RunID id, uint64_t timeout, uint64_t timestamp)
60 {
61  std::lock_guard<std::mutex> lk(primary_mutex_);
62  external_request_status_ = true;
63  report_string_ = "All is OK.";
64 #if ART_HEX_VERSION >= 0x21100
65  SetMFModuleName("Starting");
66 #endif
67 
68  TLOG(TLVL_START) << "Start transition started";
69  auto start_time = std::chrono::steady_clock::now();
70  std::string initialState = fsm_.getState().getName();
71  fsm_.start(id, timeout, timestamp);
72  if (external_request_status_)
73  {
74  std::string finalState = fsm_.getState().getName();
75 #if ART_HEX_VERSION >= 0x21100
76  SetMFModuleName(finalState);
77 #endif
78  TLOG(TLVL_DEBUG)
79  << "States before and after a start transition: "
80  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
81  }
82  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
83 
84  TLOG(TLVL_START) << "Start transition complete";
85  return (external_request_status_);
86 }
87 
88 bool artdaq::Commandable::stop(uint64_t timeout, uint64_t timestamp)
89 {
90  std::lock_guard<std::mutex> lk(primary_mutex_);
91  external_request_status_ = true;
92  report_string_ = "All is OK.";
93 #if ART_HEX_VERSION >= 0x21100
94  SetMFModuleName("Stopping");
95 #endif
96 
97  TLOG(TLVL_STOP) << "Stop transition started";
98  auto start_time = std::chrono::steady_clock::now();
99  std::string initialState = fsm_.getState().getName();
100  fsm_.stop(timeout, timestamp);
101  if (external_request_status_)
102  {
103  std::string finalState = fsm_.getState().getName();
104 #if ART_HEX_VERSION >= 0x21100
105  SetMFModuleName(finalState);
106 #endif
107  TLOG(TLVL_DEBUG)
108  << "States before and after a stop transition: "
109  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
110  }
111  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
112 
113  TLOG(TLVL_STOP) << "Stop transition complete";
114  return (external_request_status_);
115 }
116 
117 bool artdaq::Commandable::pause(uint64_t timeout, uint64_t timestamp)
118 {
119  std::lock_guard<std::mutex> lk(primary_mutex_);
120  external_request_status_ = true;
121  report_string_ = "All is OK.";
122 #if ART_HEX_VERSION >= 0x21100
123  SetMFModuleName("Pausing");
124 #endif
125 
126  TLOG(TLVL_PAUSE) << "Pause transition started";
127  auto start_time = std::chrono::steady_clock::now();
128  std::string initialState = fsm_.getState().getName();
129  fsm_.pause(timeout, timestamp);
130  if (external_request_status_)
131  {
132  std::string finalState = fsm_.getState().getName();
133 #if ART_HEX_VERSION >= 0x21100
134  SetMFModuleName(finalState);
135 #endif
136  TLOG(TLVL_DEBUG)
137  << "States before and after a pause transition: "
138  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
139  }
140  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
141 
142  TLOG(TLVL_PAUSE) << "Pause transition complete";
143  return (external_request_status_);
144 }
145 
146 bool artdaq::Commandable::resume(uint64_t timeout, uint64_t timestamp)
147 {
148  std::lock_guard<std::mutex> lk(primary_mutex_);
149  external_request_status_ = true;
150  report_string_ = "All is OK.";
151 #if ART_HEX_VERSION >= 0x21100
152  SetMFModuleName("Resuming");
153 #endif
154 
155  TLOG(TLVL_RESUME) << "Resume transition started";
156  auto start_time = std::chrono::steady_clock::now();
157  std::string initialState = fsm_.getState().getName();
158  fsm_.resume(timeout, timestamp);
159  if (external_request_status_)
160  {
161  std::string finalState = fsm_.getState().getName();
162 #if ART_HEX_VERSION >= 0x21100
163  SetMFModuleName(finalState);
164 #endif
165  TLOG(TLVL_DEBUG)
166  << "States before and after a resume transition: "
167  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
168  }
169  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
170 
171  TLOG(TLVL_RESUME) << "Resume transition complete";
172  return (external_request_status_);
173 }
174 
175 bool artdaq::Commandable::shutdown(uint64_t timeout)
176 {
177  std::lock_guard<std::mutex> lk(primary_mutex_);
178  external_request_status_ = true;
179  report_string_ = "All is OK.";
180 #if ART_HEX_VERSION >= 0x21100
181  SetMFModuleName("Shutting Down");
182 #endif
183 
184  TLOG(TLVL_SHUTDOWN) << "Shutdown transition started";
185  auto start_time = std::chrono::steady_clock::now();
186  std::string initialState = fsm_.getState().getName();
187  fsm_.shutdown(timeout);
188  if (external_request_status_)
189  {
190  std::string finalState = fsm_.getState().getName();
191 #if ART_HEX_VERSION >= 0x21100
192  SetMFModuleName(finalState);
193 #endif
194  TLOG(TLVL_DEBUG)
195  << "States before and after a shutdown transition: "
196  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
197  }
198  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
199 
200  TLOG(TLVL_SHUTDOWN) << "Shutdown transition complete";
201  return (external_request_status_);
202 }
203 
204 bool artdaq::Commandable::soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
205 {
206  std::lock_guard<std::mutex> lk(primary_mutex_);
207  external_request_status_ = true;
208  report_string_ = "All is OK.";
209 #if ART_HEX_VERSION >= 0x21100
210  SetMFModuleName("Soft_initializing");
211 #endif
212 
213  TLOG(TLVL_SOFT_INIT) << "Soft_initialize transition started";
214  auto start_time = std::chrono::steady_clock::now();
215  std::string initialState = fsm_.getState().getName();
216  fsm_.soft_init(pset, timeout, timestamp);
217  if (external_request_status_)
218  {
219  std::string finalState = fsm_.getState().getName();
220 #if ART_HEX_VERSION >= 0x21100
221  SetMFModuleName(finalState);
222 #endif
223  TLOG(TLVL_DEBUG)
224  << "States before and after a soft_init transition: "
225  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
226  }
227  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
228 
229  TLOG(TLVL_SOFT_INIT) << "Soft_initialize transition complete";
230  return (external_request_status_);
231 }
232 
233 bool artdaq::Commandable::reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
234 {
235  std::lock_guard<std::mutex> lk(primary_mutex_);
236  external_request_status_ = true;
237  report_string_ = "All is OK.";
238 #if ART_HEX_VERSION >= 0x21100
239  SetMFModuleName("Reinitializing");
240 #endif
241 
242  TLOG(TLVL_REINIT) << "Reinitialize transition started";
243  auto start_time = std::chrono::steady_clock::now();
244  std::string initialState = fsm_.getState().getName();
245  fsm_.reinit(pset, timeout, timestamp);
246  if (external_request_status_)
247  {
248  std::string finalState = fsm_.getState().getName();
249 #if ART_HEX_VERSION >= 0x21100
250  SetMFModuleName(finalState);
251 #endif
252  TLOG(TLVL_DEBUG)
253  << "States before and after a reinit transition: "
254  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
255  }
256  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
257 
258  TLOG(TLVL_REINIT) << "Reinitialize transition complete";
259  return (external_request_status_);
260 }
261 
263 {
264  std::lock_guard<std::mutex> lk(primary_mutex_);
265  external_request_status_ = true;
266  report_string_ = "An error condition was reported while running.";
267 #if ART_HEX_VERSION >= 0x21100
268  SetMFModuleName("Failing");
269 #endif
270 
271  TLOG(TLVL_INRUN_FAILURE) << "In_Run_Failure transition started";
272  auto start_time = std::chrono::steady_clock::now();
273  std::string initialState = fsm_.getState().getName();
274  fsm_.in_run_failure();
275  if (external_request_status_)
276  {
277  std::string finalState = fsm_.getState().getName();
278 #if ART_HEX_VERSION >= 0x21100
279  SetMFModuleName(finalState);
280 #endif
281  TLOG(TLVL_DEBUG)
282  << "States before and after an in_run_failure transition: "
283  << initialState << " and " << finalState << ". Transition Duration: " << TimeUtils::GetElapsedTime(start_time) << " s." ;
284  }
285  if (metricMan) metricMan->sendMetric("DAQ Transition Time", TimeUtils::GetElapsedTime(start_time), "s", 4, artdaq::MetricMode::Accumulate);
286 
287  TLOG(TLVL_INRUN_FAILURE) << "in_run_failure complete";
288  return (external_request_status_);
289 }
290 
291 std::string artdaq::Commandable::status() const
292 {
293  std::lock_guard<std::mutex> lk(primary_mutex_);
294  TLOG(TLVL_STATUS) << "Status command started";
295  std::string currentState = this->current_state();
296  if (currentState == "InRunError")
297  {
298  return "Error";
299  }
300  TLOG(TLVL_STATUS) << "Status command complete";
301  return currentState;
302 }
303 
304 std::vector<std::string> artdaq::Commandable::legal_commands() const
305 {
306  std::lock_guard<std::mutex> lk(primary_mutex_);
307  TLOG(TLVL_LEGAL_COMMANDS) << "legal_commands started";
308  std::string currentState = this->current_state();
309 
310  if (currentState == "Ready")
311  {
312  return { "init", "soft_init", "start", "shutdown" };
313  }
314  if (currentState == "Running")
315  {
316  // 12-May-2015, KAB: in_run_failure is also possible, but it
317  // shouldn't be requested externally.
318  return { "pause", "stop" };
319  }
320  if (currentState == "Paused")
321  {
322  return { "resume", "stop" };
323  }
324  if (currentState == "InRunError")
325  {
326  return { "pause", "stop" };
327  }
328 
329  // Booted and Error
330  TLOG(TLVL_LEGAL_COMMANDS) << "legal_commands complete";
331  return { "init", "shutdown" };
332 }
333 
334 // *******************************************************************
335 // *** The following methods implement the state machine operations.
336 // *******************************************************************
337 
338 bool artdaq::Commandable::do_initialize(fhicl::ParameterSet const&, uint64_t, uint64_t)
339 {
340  TLOG(TLVL_DEBUG) << "do_initialize called." ;
341  external_request_status_ = true;
342  return external_request_status_;
343 }
344 
345 bool artdaq::Commandable::do_start(art::RunID, uint64_t, uint64_t)
346 {
347  TLOG(TLVL_DEBUG) << "do_start called." ;
348  external_request_status_ = true;
349  return external_request_status_;
350 }
351 
352 bool artdaq::Commandable::do_stop(uint64_t, uint64_t)
353 {
354  TLOG(TLVL_DEBUG) << "do_stop called." ;
355  external_request_status_ = true;
356  return external_request_status_;
357 }
358 
359 bool artdaq::Commandable::do_pause(uint64_t, uint64_t)
360 {
361  TLOG(TLVL_DEBUG) << "do_pause called." ;
362  external_request_status_ = true;
363  return external_request_status_;
364 }
365 
366 bool artdaq::Commandable::do_resume(uint64_t, uint64_t)
367 {
368  TLOG(TLVL_DEBUG) << "do_resume called." ;
369  external_request_status_ = true;
370  return external_request_status_;
371 }
372 
374 {
375  TLOG(TLVL_DEBUG) << "do_shutdown called." ;
376  external_request_status_ = true;
377  return external_request_status_;
378 }
379 
380 bool artdaq::Commandable::do_reinitialize(fhicl::ParameterSet const&, uint64_t, uint64_t)
381 {
382  TLOG(TLVL_DEBUG) << "do_reinitialize called." ;
383  external_request_status_ = true;
384  return external_request_status_;
385 }
386 
387 bool artdaq::Commandable::do_soft_initialize(fhicl::ParameterSet const&, uint64_t, uint64_t)
388 {
389  TLOG(TLVL_DEBUG) << "do_soft_initialize called." ;
390  external_request_status_ = true;
391  return external_request_status_;
392 }
393 
394 void artdaq::Commandable::badTransition(const std::string& trans)
395 {
396  std::string currentState = this->current_state();
397  if (currentState == "InRunError")
398  {
399  currentState = "Error";
400  }
401 
402  report_string_ = "An invalid transition (";
403  report_string_.append(trans);
404  report_string_.append(") was requested; transition not allowed from this process's current state of \"");
405  report_string_.append(currentState);
406  report_string_.append("\"");
407 
408  TLOG(TLVL_WARNING) << report_string_ ;
409 
410  external_request_status_ = false;
411 }
412 
414 {
415  TLOG(TLVL_DEBUG) << "BootedEnter called." ;
416 }
417 
419 {
420  TLOG(TLVL_DEBUG) << "InRunExit called." ;
421 }
422 
423 
424 std::string artdaq::Commandable::do_trace_get(std::string const& name)
425 {
426  TLOG(TLVL_DEBUG) << "Getting masks for name " << name ;
427  std::ostringstream ss;
428  if (name == "ALL")
429  {
430  unsigned ii = 0;
431  unsigned ee = traceControl_p->num_namLvlTblEnts;
432  for (ii = 0; ii < ee; ++ii)
433  {
434  if (traceNamLvls_p[ii].name[0])
435  ss << traceNamLvls_p[ii].name << " " << std::hex << std::showbase << traceNamLvls_p[ii].M << " " << traceNamLvls_p[ii].S << " " << traceNamLvls_p[ii].T << " " << std::endl;
436  }
437  }
438  else
439  {
440  unsigned ii = 0;
441  unsigned ee = traceControl_p->num_namLvlTblEnts;
442  for (ii = 0; ii < ee; ++ii)
443  {
444  if (traceNamLvls_p[ii].name[0] && TMATCHCMP(name.c_str(), traceNamLvls_p[ii].name)) break;
445  }
446  if (ii == ee) return "";
447 
448  ss << std::hex << traceNamLvls_p[ii].M << " " << traceNamLvls_p[ii].S << " " << traceNamLvls_p[ii].T;
449  }
450  return ss.str();
451 }
452 
453 bool artdaq::Commandable::do_trace_set(std::string const& type, std::string const& name, uint64_t mask)
454 {
455  TLOG(TLVL_DEBUG) << "Setting msk " << type << " for name " << name << " to " << std::hex << std::showbase << mask ;
456  if (name != "ALL")
457  {
458  if (type.size() > 0) {
459  switch (type[0])
460  {
461  case 'M':
462  TRACE_CNTL("lvlmsknM", name.c_str(), mask);
463  break;
464  case 'S':
465  TRACE_CNTL("lvlmsknS", name.c_str(), mask);
466  break;
467  case 'T':
468  TRACE_CNTL("lvlmsknT", name.c_str(), mask);
469  break;
470  }
471  }
472  else
473  {
474  TLOG(TLVL_ERROR) << "Cannot set mask: no type specified!" ;
475  }
476  }
477  else
478  {
479  if (type.size() > 0) {
480  switch (type[0])
481  {
482  case 'M':
483  TRACE_CNTL("lvlmskMg", mask);
484  break;
485  case 'S':
486  TRACE_CNTL("lvlmskSg", mask);
487  break;
488  case 'T':
489  TRACE_CNTL("lvlmskTg", mask);
490  break;
491  }
492  }
493  else
494  {
495  TLOG(TLVL_ERROR) << "Cannot set mask: no type specified!" ;
496  }
497  }
498  return true;
499 }
500 
501 bool artdaq::Commandable::do_meta_command(std::string const& cmd, std::string const& arg)
502 {
503  TLOG(TLVL_DEBUG) << "Meta-Command called: cmd=" << cmd << ", arg=" << arg ;
504  return true;
505 }
506 
507 // *********************
508 // *** Utility methods.
509 // *********************
510 
512 {
513  std::string fullStateName = (const_cast<Commandable*>(this))->fsm_.getState().getName();
514  size_t pos = fullStateName.rfind("::");
515  if (pos != std::string::npos)
516  {
517  return fullStateName.substr(pos + 2);
518  }
519  else
520  {
521  return fullStateName;
522  }
523 }
bool initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Processes the initialize request.
Definition: Commandable.cc:29
virtual bool do_start(art::RunID, uint64_t, uint64_t)
Perform the start transition.
Definition: Commandable.cc:345
Commandable is the base class for all artdaq components which implement the artdaq state machine...
Definition: Commandable.hh:20
virtual void badTransition(const std::string &trans)
This function is called when an attempt is made to call an illegal transition.
Definition: Commandable.cc:394
virtual bool do_trace_set(std::string const &, std::string const &, uint64_t)
Set the given TRACE mask for the given trace name.
Definition: Commandable.cc:453
virtual void InRunExit()
Perform actions upon leaving the InRun state.
Definition: Commandable.cc:418
virtual std::string do_trace_get(std::string const &)
Get the TRACE mask for the given trace name.
Definition: Commandable.cc:424
virtual bool do_pause(uint64_t, uint64_t)
Perform the pause transition.
Definition: Commandable.cc:359
bool reinitialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Processes the reinitialize request.
Definition: Commandable.cc:233
std::string current_state() const
Return the name of the current state.
Definition: Commandable.cc:511
virtual void BootedEnter()
Perform actions upon entering the Booted state.
Definition: Commandable.cc:413
std::string status() const
Returns the current state of the Commandable.
Definition: Commandable.cc:291
virtual bool do_shutdown(uint64_t)
Perform the shutdown transition.
Definition: Commandable.cc:373
virtual bool do_soft_initialize(fhicl::ParameterSet const &, uint64_t, uint64_t)
Perform the soft_initialize transition.
Definition: Commandable.cc:387
bool resume(uint64_t timeout, uint64_t timestamp)
Processes the resume transition.
Definition: Commandable.cc:146
bool pause(uint64_t timeout, uint64_t timestamp)
Processes the pause transition.
Definition: Commandable.cc:117
virtual bool do_stop(uint64_t, uint64_t)
Perform the stop transition.
Definition: Commandable.cc:352
virtual bool do_meta_command(std::string const &, std::string const &)
Run a module-defined command with the given parameter string.
Definition: Commandable.cc:501
bool in_run_failure()
Actions taken when the in_run_failure state is set.
Definition: Commandable.cc:262
std::vector< std::string > legal_commands() const
Get the legal transition commands from the current state.
Definition: Commandable.cc:304
bool soft_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Processes the soft-initialize request.
Definition: Commandable.cc:204
virtual bool do_resume(uint64_t, uint64_t)
Perform the resume transition.
Definition: Commandable.cc:366
bool start(art::RunID id, uint64_t timeout, uint64_t timestamp)
Processes the start transition.
Definition: Commandable.cc:59
virtual bool do_reinitialize(fhicl::ParameterSet const &, uint64_t, uint64_t)
Perform the reinitialize transition.
Definition: Commandable.cc:380
bool stop(uint64_t timeout, uint64_t timestamp)
Processes the stop transition.
Definition: Commandable.cc:88
virtual bool do_initialize(fhicl::ParameterSet const &, uint64_t, uint64_t)
Perform the initialize transition.
Definition: Commandable.cc:338
bool shutdown(uint64_t timeout)
Processes the shutdown transition.
Definition: Commandable.cc:175