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