artdaq  v3_07_02
xmlrpc_commander.cc
1 /* DarkSide 50 DAQ program
2  * This file add the xmlrpc commander as a client to the SC
3  * Author: Alessandro Razeto <Alessandro.Razeto@ge.infn.it>
4  */
5 
6 #pragma GCC diagnostic push
7 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
8 #define _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES 1
9 #include <xmlrpc-c/base.hpp>
10 #include <xmlrpc-c/client_simple.hpp>
11 #include <xmlrpc-c/girerr.hpp>
12 #include <xmlrpc-c/registry.hpp>
13 #include <xmlrpc-c/server_abyss.hpp>
14 #undef _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
15 #pragma GCC diagnostic pop
16 #include <cstdint>
17 #include <iostream>
18 #include <limits>
19 #include <memory>
20 #include <stdexcept>
21 #include "artdaq/DAQdata/Globals.hh"
22 #define TRACE_NAME (app_name + "_xmlrpc_commander").c_str()
23 #include "tracemf.h"
24 
25 #include <errno.h>
26 #include <netinet/in.h>
27 #include <sys/socket.h>
28 #include <cstring>
29 #include <exception>
30 #include "artdaq-core/Utilities/ExceptionHandler.hh"
31 
32 #include "canvas/Persistency/Provenance/RunID.h"
33 #include "fhiclcpp/make_ParameterSet.h"
34 
35 #include "artdaq/ExternalComms/xmlrpc_commander.hh"
36 //#include "artdaq/Application/LoadParameterSet.hh"
37 
38 namespace {
42 class env_wrap
43 {
44 public:
45  env_wrap() { xmlrpc_env_init(&this->env_c); };
46  ~env_wrap() { xmlrpc_env_clean(&this->env_c); };
47  xmlrpc_env env_c;
48 };
49 } // namespace
50 static xmlrpc_c::paramList
51 pListFromXmlrpcArray(xmlrpc_value* const arrayP)
52 {
53  env_wrap env;
54  XMLRPC_ASSERT_ARRAY_OK(arrayP);
55  unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP);
56  assert(!env.env_c.fault_occurred);
57  xmlrpc_c::paramList paramList(arraySize);
58  for (unsigned int i = 0; i < arraySize; ++i)
59  {
60  xmlrpc_value* arrayItemP;
61  xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP);
62  assert(!env.env_c.fault_occurred);
63  paramList.add(xmlrpc_c::value(arrayItemP));
64  xmlrpc_DECREF(arrayItemP);
65  }
66  return paramList;
67 }
68 static xmlrpc_value*
69 c_executeMethod(xmlrpc_env* const envP,
70  xmlrpc_value* const paramArrayP,
71  void* const methodPtr,
72  void* const callInfoPtr)
73 {
74  xmlrpc_c::method* const methodP(static_cast<xmlrpc_c::method*>(methodPtr));
75  xmlrpc_c::paramList const paramList(pListFromXmlrpcArray(paramArrayP));
76  xmlrpc_c::callInfo* const callInfoP(static_cast<xmlrpc_c::callInfo*>(callInfoPtr));
77  xmlrpc_value* retval;
78  retval = NULL; // silence used-before-set warning
79  try
80  {
81  xmlrpc_c::value result;
82  try
83  {
84  xmlrpc_c::method2* const method2P(dynamic_cast<xmlrpc_c::method2*>(methodP));
85  if (method2P)
86  method2P->execute(paramList, callInfoP, &result);
87  else
88  methodP->execute(paramList, &result);
89  }
90  catch (xmlrpc_c::fault const& fault)
91  {
92  xmlrpc_env_set_fault(envP, fault.getCode(),
93  fault.getDescription().c_str());
94  }
95  if (!envP->fault_occurred)
96  {
97  if (result.isInstantiated())
98  retval = result.cValue();
99  else
100  girerr::throwf(
101  "Xmlrpc-c user's xmlrpc_c::method object's "
102  "'execute method' failed to set the RPC result "
103  "value.");
104  }
105  }
106  catch (std::exception const& e)
107  {
108  xmlrpc_faultf(envP,
109  "Unexpected error executing code for "
110  "particular method, detected by Xmlrpc-c "
111  "method registry code. Method did not "
112  "fail; rather, it did not complete at all. %s",
113  e.what());
114  }
115  catch (...)
116  {
117  xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
118  "Unexpected error executing code for "
119  "particular method, detected by Xmlrpc-c "
120  "method registry code. Method did not "
121  "fail; rather, it did not complete at all.");
122  }
123  return retval;
124 }
125 
126 namespace artdaq {
133 std::string exception_msg(const std::runtime_error& er,
134  const std::string& helpText = "execute request")
135 {
136  std::string msg("Exception when trying to ");
137  msg.append(helpText);
138  msg.append(": ");
139  msg.append(er.what()); //std::string(er.what ()).substr (2);
140  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
141  return msg;
142 }
143 
150 std::string exception_msg(const art::Exception& er,
151  const std::string& helpText)
152 {
153  std::string msg("Exception when trying to ");
154  msg.append(helpText);
155  msg.append(": ");
156  msg.append(er.what());
157  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
158  return msg;
159 }
160 
167 std::string exception_msg(const cet::exception& er,
168  const std::string& helpText)
169 {
170  std::string msg("Exception when trying to ");
171  msg.append(helpText);
172  msg.append(": ");
173  msg.append(er.what());
174  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
175  return msg;
176 }
177 
184 std::string exception_msg(const std::string& erText,
185  const std::string& helpText)
186 {
187  std::string msg("Exception when trying to ");
188  msg.append(helpText);
189  msg.append(": ");
190  msg.append(erText);
191  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
192  return msg;
193 }
194 
212 class cmd_ : public xmlrpc_c::method
213 {
214 public:
215  // Can't seem to initialize "_signature" and "_help" in the initialization list...
222  cmd_(xmlrpc_commander& c, const std::string& signature, const std::string& description)
223  : _c(c)
224  {
225  _signature = signature;
226  _help = description;
227  }
228 
234  void execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) final;
235 
236 protected:
238 
244  virtual bool execute_(const xmlrpc_c::paramList&, xmlrpc_c::value* const retvalP) = 0;
245 
255  template<typename T>
256  T getParam(const xmlrpc_c::paramList& paramList, int index);
257 
281  template<typename T>
282  T getParam(const xmlrpc_c::paramList& paramList, int index, T default_value);
283 };
284 
285 // Users are only allowed to call getParam for predefined types; see
286 // template specializations below this default function
287 
288 template<typename T>
289 T cmd_::getParam(const xmlrpc_c::paramList&, int)
290 {
291  throw cet::exception("cmd_") << "Error in cmd_::getParam(): value type not supported" << std::endl;
292 }
293 
302 template<>
303 uint64_t cmd_::getParam<uint64_t>(const xmlrpc_c::paramList& paramList, int index)
304 {
305  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint64_t.";
306  TLOG(TLVL_TRACE) << "Param value: " << paramList.getI8(index);
307  return static_cast<uint64_t>(paramList.getI8(index));
308 }
309 
318 template<>
319 uint32_t cmd_::getParam<uint32_t>(const xmlrpc_c::paramList& paramList, int index)
320 {
321  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint32_t.";
322  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
323  return static_cast<uint32_t>(paramList.getInt(index));
324 }
325 
334 template<>
335 std::string cmd_::getParam<std::string>(const xmlrpc_c::paramList& paramList, int index)
336 {
337  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as string.";
338  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
339  return static_cast<std::string>(paramList.getString(index));
340 }
341 
350 template<>
351 art::RunID cmd_::getParam<art::RunID>(const xmlrpc_c::paramList& paramList, int index)
352 {
353  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as Run Number.";
354  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
355  art::RunNumber_t run_number(paramList.getInt(index));
356  art::RunID run_id(run_number);
357 
358  return run_id;
359 }
360 
369 template<>
370 fhicl::ParameterSet cmd_::getParam<fhicl::ParameterSet>(const xmlrpc_c::paramList& paramList, int index)
371 {
372  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as ParameterSet.";
373  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
374  std::string configString = std::string(paramList.getString(index).c_str());
375  TLOG(TLVL_DEBUG) << "Loading Parameter Set from string: " << configString << std::endl;
376  fhicl::ParameterSet pset;
377 
378  try
379  {
380  fhicl::make_ParameterSet(configString, pset);
381  }
382  catch (const fhicl::exception& e)
383  {
384  if (getenv("FHICL_FILE_PATH") == nullptr)
385  {
386  std::cerr << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
387  setenv("FHICL_FILE_PATH", ".", 0);
388  }
389  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
390  fhicl::make_ParameterSet(configString, lookup_policy, pset);
391  }
392 
393  TLOG(TLVL_INFO) << "Parameter Set Loaded." << std::endl;
394  return pset;
395 }
396 
397 template<typename T>
398 T cmd_::getParam(const xmlrpc_c::paramList& paramList, int index,
399  T default_value)
400 {
401  T val = default_value;
402 
403  try
404  {
405  val = getParam<T>(paramList, index);
406  }
407  catch (const cet::exception& exception)
408  {
409  throw exception;
410  }
411  catch (...)
412  {}
413 
414  return val;
415 }
416 
417 void cmd_::execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP)
418 {
419  std::unique_lock<std::timed_mutex> lk(_c.mutex_, std::chrono::milliseconds(250));
420  if (lk.owns_lock())
421  {
422  try
423  {
424  // JCF, 9/4/14
425 
426  // Assuming the execute_ function returns true, then if the
427  // retvalP argument was untouched, assign it the string
428  // "Success"
429 
430  // See
431  // http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#isinstantiated
432  // for more on the concept of instantiation in xmlrpc_c::value objects
433 
434  if (execute_(paramList, retvalP))
435  {
436  if (!retvalP->isInstantiated())
437  {
438  *retvalP = xmlrpc_c::value_string("Success");
439  }
440  }
441  else
442  {
443  std::string problemReport = _c._commandable.report("transition_status");
444  *retvalP = xmlrpc_c::value_string(problemReport);
445  }
446  }
447  catch (std::runtime_error& er)
448  {
449  std::string msg = exception_msg(er, _help);
450  *retvalP = xmlrpc_c::value_string(msg);
451  TLOG(TLVL_ERROR) << msg;
452  }
453  catch (art::Exception& er)
454  {
455  std::string msg = exception_msg(er, _help);
456  *retvalP = xmlrpc_c::value_string(msg);
457  TLOG(TLVL_ERROR) << msg;
458  }
459  catch (cet::exception& er)
460  {
461  std::string msg = exception_msg(er, _help);
462  *retvalP = xmlrpc_c::value_string(msg);
463  TLOG(TLVL_ERROR) << msg;
464  }
465  catch (...)
466  {
467  std::string msg = exception_msg("Unknown exception", _help);
468  *retvalP = xmlrpc_c::value_string(msg);
469  TLOG(TLVL_ERROR) << msg;
470  }
471  }
472  else
473  {
474  *retvalP = xmlrpc_c::value_string("busy");
475  }
476 }
477 
479 
480 // JCF, 9/5/14
481 
482 // The three "init" transitions all take a FHiCL parameter list, and
483 // optionally a timeout and a timestamp; thus we can kill three birds
484 // with one stone in the GENERATE_INIT_TRANSITION macro
485 
486 #define GENERATE_INIT_TRANSITION(NAME, CALL, DESCRIPTION) \
487  \
488  class NAME##_ : public cmd_ \
489  { \
490  public: \
491  \
494  explicit NAME##_(xmlrpc_commander& c) : cmd_(c, "s:sII", DESCRIPTION) {} \
495  \
496  \
497  static const uint64_t defaultTimeout = 45; \
498  \
499  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
500  \
501  private: \
502  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) \
503  { \
504  fhicl::ParameterSet ps; \
505  try \
506  { \
507  ps = getParam<fhicl::ParameterSet>(paramList, 0); \
508  } \
509  catch (...) \
510  { \
511  *retvalP = xmlrpc_c::value_string("Error: The " #NAME " message requires a single argument that is a string containing the initialization ParameterSet"); \
512  return true; \
513  } \
514  \
515  return _c._commandable.CALL(ps, \
516  getParam<uint64_t>(paramList, 1, defaultTimeout), \
517  getParam<uint64_t>(paramList, 2, defaultTimestamp)); \
518  } \
519  };
520 
521 GENERATE_INIT_TRANSITION(init, initialize, "initialize the program")
522 
523 GENERATE_INIT_TRANSITION(soft_init, soft_initialize, "initialize software components in the program")
524 
525 GENERATE_INIT_TRANSITION(reinit, reinitialize, "re-initialize the program")
526 
527 #undef GENERATE_INIT_TRANSITION
528 
530 
534 class start_ : public cmd_
535 {
536 public:
542  : cmd_(c, "s:iII", "start the run")
543  {}
544 
546  static const uint64_t defaultTimeout = 45;
548  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max();
549 
550 private:
551  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
552  {
553  try
554  {
555  getParam<art::RunID>(paramList, 0);
556  }
557  catch (...)
558  {
559  *retvalP = xmlrpc_c::value_string("Error: The start message requires the run number as an argument.");
560  return true;
561  }
562 
563  return _c._commandable.start(getParam<art::RunID>(paramList, 0),
564  getParam<uint64_t>(paramList, 1, defaultTimeout),
565  getParam<uint64_t>(paramList, 2, defaultTimestamp));
566  }
567 };
568 
570 
571 // JCF, 9/5/14
572 
573 // "pause", "resume" and "stop" all take an optional timeout and
574 // timestamp parameter, so we can generate them all with the
575 // GENERATE_TIMEOUT_TIMESTAMP_TRANSITION macro
576 
577 #define GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(NAME, CALL, DESCRIPTION, TIMEOUT) \
578  \
579  class NAME##_ : public cmd_ \
580  { \
581  public: \
582  \
584  NAME##_(xmlrpc_commander& c) : cmd_(c, "s:II", DESCRIPTION) {} \
585  \
586  \
587  static const uint64_t defaultTimeout = TIMEOUT; \
588  \
589  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
590  \
591  private: \
592  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const) \
593  { \
594  return _c._commandable.CALL(getParam<uint64_t>(paramList, 0, defaultTimeout), \
595  getParam<uint64_t>(paramList, 1, defaultTimestamp)); \
596  } \
597  };
598 
599 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(pause, pause, "pause the program", 45)
600 
601 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(resume, resume, "resume the program", 45)
602 
603 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(stop, stop, "stop the program", 45)
604 
605 #undef GENERATE_TIMEOUT_TIMESTAMP_TRANSITION
606 
610 class shutdown_ : public cmd_
611 {
612 public:
618  : cmd_(c, "s:i", "shutdown the program")
619  {}
620 
622  static const uint64_t defaultTimeout = 45;
623 
624 private:
625  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const)
626  {
627  auto ret = _c._commandable.shutdown(getParam<uint64_t>(paramList, 0, defaultTimeout));
628 
629 #if 1
630  if (_c.server) _c.server->terminate();
631 #endif
632 
633  return ret;
634  }
635 };
636 
640 class status_ : public cmd_
641 {
642 public:
648  : cmd_(c, "s:n", "report the current state")
649  {}
650 
651 private:
652  bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const retvalP)
653  {
654  *retvalP = xmlrpc_c::value_string(_c._commandable.status());
655  return true;
656  }
657 };
658 
662 class report_ : public cmd_
663 {
664 public:
670  : cmd_(c, "s:s", "report statistics")
671  {}
672 
673 private:
674  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
675  {
676  try
677  {
678  getParam<std::string>(paramList, 0);
679  }
680  catch (...)
681  {
682  *retvalP = xmlrpc_c::value_string("Error: The report message requires a single argument that selects the type of statistics to be reported.");
683  return true;
684  }
685 
686  *retvalP = xmlrpc_c::value_string(_c._commandable.report(getParam<std::string>(paramList, 0)));
687  return true;
688  }
689 };
690 
694 class legal_commands_ : public cmd_
695 {
696 public:
702  : cmd_(c, "s:n", "return the currently legal commands")
703  {}
704 
705 private:
706  bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const retvalP)
707  {
708  std::vector<std::string> cmdList = _c._commandable.legal_commands();
709  std::string resultString;
710 
711  for (auto& cmd : cmdList)
712  {
713  resultString.append(cmd + " ");
714  if (cmd == "shutdown")
715  {
716  resultString.append(" reset");
717  }
718  }
719  *retvalP = xmlrpc_c::value_string(resultString);
720 
721  return true;
722  }
723 };
724 
728 class register_monitor_ : public cmd_
729 {
730 public:
736  : cmd_(c, "s:s", "Get notified of a new monitor")
737  {}
738 
739 private:
740  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
741  {
742  try
743  {
744  getParam<fhicl::ParameterSet>(paramList, 0);
745  }
746  catch (...)
747  {
748  *retvalP = xmlrpc_c::value_string("Error: The register_monitor command expects a string representing the FHiCL definition of a Transfer plugin");
749  return true;
750  }
751 
752  *retvalP = xmlrpc_c::value_string(_c._commandable.register_monitor(getParam<fhicl::ParameterSet>(paramList, 0)));
753  return true;
754  }
755 };
756 
760 class unregister_monitor_ : public cmd_
761 {
762 public:
768  : cmd_(c, "s:s", "Remove a monitor")
769  {}
770 
771 private:
772  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
773  {
774  try
775  {
776  getParam<std::string>(paramList, 0);
777  }
778  catch (...)
779  {
780  *retvalP = xmlrpc_c::value_string("Error: The unregister_monitor command expects a string representing the label of the monitor to be removed");
781  return true;
782  }
783 
784  *retvalP = xmlrpc_c::value_string(_c._commandable.unregister_monitor(getParam<std::string>(paramList, 0)));
785  return true;
786  }
787 };
788 
792 class trace_set_ : public cmd_
793 {
794 public:
800  : cmd_(c, "s:ssI", "Set TRACE mask")
801  {}
802 
803 private:
804  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
805  {
806  try
807  {
808  getParam<std::string>(paramList, 0);
809  getParam<std::string>(paramList, 1);
810  getParam<std::string>(paramList, 2);
811  }
812  catch (...)
813  {
814  *retvalP = xmlrpc_c::value_string("Error: The trace_set command expects a name (ALL for all), a mask type (M, S , or T), and a mask");
815  return true;
816  }
817 
818  return _c._commandable.do_trace_set(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1), getParam<std::string>(paramList, 2));
819  }
820 };
821 
825 class trace_get_ : public cmd_
826 {
827 public:
833  : cmd_(c, "s:s", "Get TRACE mask")
834  {}
835 
836 private:
837  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
838  {
839  try
840  {
841  getParam<std::string>(paramList, 0);
842  }
843  catch (...)
844  {
845  *retvalP = xmlrpc_c::value_string("Error: The trace_get command expects a name (ALL for all)");
846  return true;
847  }
848 
849  *retvalP = xmlrpc_c::value_string(_c._commandable.do_trace_get(getParam<std::string>(paramList, 0)));
850  return true;
851  }
852 };
853 
857 class meta_command_ : public cmd_
858 {
859 public:
865  : cmd_(c, "s:ss", "Run custom command")
866  {}
867 
868 private:
869  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
870  {
871  try
872  {
873  getParam<std::string>(paramList, 0);
874  getParam<std::string>(paramList, 1);
875  }
876  catch (...)
877  {
878  *retvalP = xmlrpc_c::value_string("Error: The meta_command command expects a string command and a string argument");
879  return true;
880  }
881 
882  return _c._commandable.do_meta_command(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
883  }
884 };
885 
889 class rollover_subrun_ : public cmd_
890 {
891 public:
897  : cmd_(c, "s:Ii", "create a new subrun")
898  {}
899 
900  static const uint64_t defaultSequenceID = 0xFFFFFFFFFFFFFFFF;
901  static const uint32_t defaultSubrunNumber = 1;
902 
903 private:
904  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const)
905  {
906  auto ret = _c._commandable.do_rollover_subrun(getParam<uint64_t>(paramList, 0, defaultSequenceID), getParam<uint32_t>(paramList, 1, defaultSubrunNumber));
907  return ret;
908  }
909 };
910 
915 {
916 public:
922  : cmd_(c, "s:ss", "Add an entry to the configuration archive list")
923  {}
924 
925 private:
926  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
927  {
928  try
929  {
930  getParam<std::string>(paramList, 0);
931  getParam<std::string>(paramList, 1);
932  }
933  catch (...)
934  {
935  *retvalP = xmlrpc_c::value_string("Error: The add_config_archive_entry command expects a string key and a string value");
936  return true;
937  }
938 
939  return _c._commandable.do_add_config_archive_entry(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
940  }
941 };
942 
947 {
948 public:
954  : cmd_(c, "s:n", "Clear the configuration archive list")
955  {}
956 
957 private:
958  bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const)
959  {
961  }
962 };
963 
964 // JCF, 9/4/14
965 
966 // Not sure if anyone was planning to resurrect this code by changing
967 // the preprocessor decision; as such, I'll leave it in for now...
968 
969 #if 0
970  class shutdown_ : public xmlrpc_c::registry::shutdown
971  {
972  public:
973  shutdown_(xmlrpc_c::serverAbyss *server) : _server(server) {}
974 
975  virtual void doit(const std::string& paramString, void*) const
976  {
977  TLOG(TLVL_INFO) << "A shutdown command was sent "
978  << "with parameter "
979  << paramString << "\"";
980  _server->terminate();
981  }
982  private:
983  xmlrpc_c::serverAbyss *_server;
984  };
985 #endif
986 
987 xmlrpc_commander::xmlrpc_commander(fhicl::ParameterSet ps, artdaq::Commandable& commandable)
988  : CommanderInterface(ps, commandable)
989  , port_(ps.get<int>("id", 0))
990  , serverUrl_(ps.get<std::string>("server_url", ""))
991  , server(nullptr)
992 {
993  if (serverUrl_ == "")
994  {
995  char hostname[HOST_NAME_MAX];
996  gethostname(hostname, HOST_NAME_MAX);
997  serverUrl_ = std::string(hostname);
998  }
999  if (serverUrl_.find("http") == std::string::npos)
1000  {
1001  serverUrl_ = "http://" + serverUrl_;
1002  }
1003  if (serverUrl_.find(std::to_string(port_)) == std::string::npos && serverUrl_.find(':', 7) == std::string::npos)
1004  {
1005  serverUrl_ = serverUrl_ + ":" + std::to_string(port_);
1006  }
1007  if (serverUrl_.find("RPC2") == std::string::npos)
1008  {
1009  serverUrl_ = serverUrl_ + "/RPC2";
1010  }
1011  TLOG(TLVL_INFO) << "XMLRPC COMMANDER CONSTRUCTOR: Port: " << port_ << ", Server Url: " << serverUrl_;
1012 }
1013 
1015 {
1016  //std::cout << "XMLRPC_COMMANDER RUN_SERVER CALLED!" << std::endl;
1017  xmlrpc_c::registry registry;
1018  struct xmlrpc_method_info3 methodInfo;
1019  memset(&methodInfo, 0, sizeof(methodInfo));
1020 
1021  /*#define register_method(m) \
1022  // xmlrpc_c::methodPtr const ptr_ ## m(new m ## _(*this));\
1023  registry.addMethod ("daq." #m, ptr_ ## m) */
1024 #define register_method(m) register_method2(m, 0x400000)
1025 
1026  xmlrpc_env env; // xmlrpc_env_init(&env);
1027  xmlrpc_registry*** c_registryPPP;
1028  c_registryPPP = (xmlrpc_registry***)(((char*)&registry) + sizeof(girmem::autoObject));
1029 
1030 #define register_method2(m, ss) \
1031  xmlrpc_c::method* ptr_##m(dynamic_cast<xmlrpc_c::method*>(new m##_(*this))); \
1032  std::string m##signature = ptr_##m->signature(), m##help = ptr_##m->help(); \
1033  methodInfo.methodName = "daq." #m; \
1034  methodInfo.methodFunction = &c_executeMethod; \
1035  methodInfo.serverInfo = ptr_##m; \
1036  methodInfo.stackSize = ss; \
1037  methodInfo.signatureString = &m##signature[0]; \
1038  methodInfo.help = &m##help[0]; \
1039  xmlrpc_env_init(&env); \
1040  xmlrpc_registry_add_method3(&env, **c_registryPPP, &methodInfo); \
1041  if (env.fault_occurred) throw(girerr::error(env.fault_string)); \
1042  xmlrpc_env_clean(&env)
1043 
1044  register_method2(init, 0x200000);
1045  register_method(soft_init);
1046  register_method(reinit);
1047  register_method(start);
1048  register_method(status);
1049  register_method(report);
1050  register_method(stop);
1051  register_method(pause);
1052  register_method(resume);
1053  register_method(register_monitor);
1054  register_method(unregister_monitor);
1055  register_method(legal_commands);
1056  register_method(trace_set);
1057  register_method(trace_get);
1058  register_method(meta_command);
1059  register_method(rollover_subrun);
1060  register_method(add_config_archive_entry);
1061  register_method(clear_config_archive);
1062 
1063  register_method(shutdown);
1064 
1065  // alias "daq.reset" to the internal shutdown transition
1066  xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
1067  registry.addMethod("daq.reset", ptr_reset);
1068 
1069 #undef register_method
1070 
1071  // JCF, 6/3/15
1072 
1073  // In the following code, I configure a socket to have the
1074  // SO_REUSEADDR option so that once an artdaq process closes, the
1075  // port it was communicating on becomes immediately available
1076  // (desirable if, say, the DAQ program is terminated and then
1077  // immediately restarted)
1078 
1079  // Much of the following code is cribbed from
1080  // http://fossies.org/linux/freeswitch/libs/xmlrpc-c/src/cpp/test/server_abyss.cpp
1081 
1082  // Below, "0" is the default protocol (in this case, given the IPv4
1083  // Protocol Family (PF_INET) and the SOCK_STREAM communication
1084  // method)
1085 
1086  XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
1087 
1088  if (socket_file_descriptor < 0)
1089  {
1090  throw cet::exception("xmlrpc_commander::run") << "Problem with the socket() call; C-style errno == " << errno << " (" << strerror(errno) << ")";
1091  }
1092 
1093  int enable = 1;
1094  int retval = setsockopt(socket_file_descriptor,
1095  SOL_SOCKET, SO_REUSEADDR,
1096  &enable, sizeof(int));
1097 
1098  if (retval < 0)
1099  {
1100  throw cet::exception("xmlrpc_commander::run") << "Problem with the call to setsockopt(); C-style errno == " << errno << " (" << strerror(errno) << ")";
1101  }
1102 
1103  struct sockaddr_in sockAddr;
1104 
1105  sockAddr.sin_family = AF_INET;
1106  sockAddr.sin_port = htons(port_);
1107  sockAddr.sin_addr.s_addr = 0;
1108 
1109  retval = bind(socket_file_descriptor,
1110  reinterpret_cast<struct sockaddr*>(&sockAddr),
1111  sizeof(sockAddr));
1112 
1113  if (retval != 0)
1114  {
1115  close(socket_file_descriptor);
1116  throw cet::exception("xmlrpc_commander::run") << "Problem with the bind() call; C-style errno == " << errno << " (" << strerror(errno) << ")";
1117  }
1118 
1119  server.reset(new xmlrpc_c::serverAbyss(xmlrpc_c::serverAbyss::constrOpt().registryP(&registry).socketFd(socket_file_descriptor)));
1120 
1121 #if 0
1122  xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
1123  registry.setShutdown(&shutdown_obj);
1124 #endif
1125 
1126  TLOG(TLVL_DEBUG) << "running server";
1127 
1128  // JCF, 6/3/15
1129 
1130  // Use a catch block to clean up (i.e., close the socket). An
1131  // opportunity for RAII, although all control paths are limited to
1132  // this section of the file...
1133 
1134  try
1135  {
1136  running_ = true;
1137  server->run();
1138  running_ = false;
1139  }
1140  catch (...)
1141  {
1142  TLOG(TLVL_WARNING) << "server threw an exception; closing the socket and rethrowing";
1143  running_ = false;
1144  close(socket_file_descriptor);
1145  throw;
1146  }
1147 
1148  close(socket_file_descriptor);
1149  TLOG(TLVL_DEBUG) << "server terminated";
1150 }
1151 catch (...)
1152 {
1153  throw;
1154 }
1155 
1156 std::string xmlrpc_commander::send_command_(std::string command)
1157 {
1158  if (serverUrl_ == "")
1159  {
1160  std::stringstream errmsg;
1161  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1162  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1163  }
1164  xmlrpc_c::clientSimple myClient;
1165  xmlrpc_c::value result;
1166 
1167  try
1168  {
1169  myClient.call(serverUrl_, "daq." + command, "", &result);
1170  }
1171  catch (...)
1172  {
1173  std::stringstream errmsg;
1174  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1175  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1176  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1177  }
1178 
1179  return xmlrpc_c::value_string(result);
1180 }
1181 
1182 std::string xmlrpc_commander::send_command_(std::string command, std::string arg)
1183 {
1184  if (serverUrl_ == "")
1185  {
1186  std::stringstream errmsg;
1187  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1188  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1189  }
1190  xmlrpc_c::clientSimple myClient;
1191  xmlrpc_c::value result;
1192 
1193  try
1194  {
1195  myClient.call(serverUrl_, "daq." + command, "s", &result, arg.c_str());
1196  }
1197  catch (...)
1198  {
1199  std::stringstream errmsg;
1200  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1201  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1202  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1203  }
1204 
1205  return xmlrpc_c::value_string(result);
1206 }
1207 
1208 std::string xmlrpc_commander::send_command_(std::string command, fhicl::ParameterSet pset, uint64_t timestamp, uint64_t timeout)
1209 {
1210  if (serverUrl_ == "")
1211  {
1212  std::stringstream errmsg;
1213  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1214  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1215  }
1216  xmlrpc_c::clientSimple myClient;
1217  xmlrpc_c::value result;
1218 
1219  try
1220  {
1221  myClient.call(serverUrl_, "daq." + command, "sII", &result, pset.to_string().c_str(), timestamp, timeout);
1222  }
1223  catch (...)
1224  {
1225  std::stringstream errmsg;
1226  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1227  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1228  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1229  }
1230 
1231  return xmlrpc_c::value_string(result);
1232 }
1233 
1234 std::string artdaq::xmlrpc_commander::send_command_(std::string command, uint64_t a, uint64_t b)
1235 {
1236  if (serverUrl_ == "")
1237  {
1238  std::stringstream errmsg;
1239  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1240  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1241  }
1242  xmlrpc_c::clientSimple myClient;
1243  xmlrpc_c::value result;
1244 
1245  try
1246  {
1247  myClient.call(serverUrl_, "daq." + command, "II", &result, a, b);
1248  }
1249  catch (...)
1250  {
1251  std::stringstream errmsg;
1252  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1253  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1254  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1255  }
1256 
1257  return xmlrpc_c::value_string(result);
1258 }
1259 
1260 std::string artdaq::xmlrpc_commander::send_command_(std::string command, art::RunID r, uint64_t a, uint64_t b)
1261 {
1262  if (serverUrl_ == "")
1263  {
1264  std::stringstream errmsg;
1265  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1266  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1267  }
1268  xmlrpc_c::clientSimple myClient;
1269  xmlrpc_c::value result;
1270 
1271  try
1272  {
1273  myClient.call(serverUrl_, "daq." + command, "iII", &result, r.run(), a, b);
1274  }
1275  catch (...)
1276  {
1277  std::stringstream errmsg;
1278  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1279  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1280  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1281  }
1282 
1283  return xmlrpc_c::value_string(result);
1284 }
1285 
1286 std::string artdaq::xmlrpc_commander::send_command_(std::string command, uint64_t arg1)
1287 {
1288  if (serverUrl_ == "")
1289  {
1290  std::stringstream errmsg;
1291  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1292  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1293  }
1294  xmlrpc_c::clientSimple myClient;
1295  xmlrpc_c::value result;
1296 
1297  try
1298  {
1299  myClient.call(serverUrl_, "daq." + command, "I", &result, arg1);
1300  }
1301  catch (...)
1302  {
1303  std::stringstream errmsg;
1304  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1305  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1306  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1307  }
1308 
1309  return xmlrpc_c::value_string(result);
1310 }
1311 
1312 std::string artdaq::xmlrpc_commander::send_command_(std::string command, std::string arg1, std::string arg2)
1313 {
1314  if (serverUrl_ == "")
1315  {
1316  std::stringstream errmsg;
1317  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1318  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1319  }
1320  xmlrpc_c::clientSimple myClient;
1321  xmlrpc_c::value result;
1322 
1323  try
1324  {
1325  myClient.call(serverUrl_, "daq." + command, "ss", &result, arg1.c_str(), arg2.c_str());
1326  }
1327  catch (...)
1328  {
1329  std::stringstream errmsg;
1330  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1331  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1332  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1333  }
1334 
1335  return xmlrpc_c::value_string(result);
1336 }
1337 
1338 std::string artdaq::xmlrpc_commander::send_command_(std::string command, std::string arg1, std::string arg2, std::string arg3)
1339 {
1340  if (serverUrl_ == "")
1341  {
1342  std::stringstream errmsg;
1343  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1344  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1345  }
1346  xmlrpc_c::clientSimple myClient;
1347  xmlrpc_c::value result;
1348 
1349  try
1350  {
1351  myClient.call(serverUrl_, "daq." + command, "sss", &result, arg1.c_str(), arg2.c_str(), arg3.c_str());
1352  }
1353  catch (...)
1354  {
1355  std::stringstream errmsg;
1356  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1357  << "; possible causes are bad arguments or nonexistent process at requested port";
1358  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1359  }
1360 
1361  return xmlrpc_c::value_string(result);
1362 }
1363 
1364 std::string xmlrpc_commander::send_register_monitor(std::string monitor_fhicl)
1365 {
1366  return send_command_("register_monitor", monitor_fhicl);
1367 }
1368 std::string xmlrpc_commander::send_unregister_monitor(std::string monitor_label)
1369 {
1370  return send_command_("unregister_monitor", monitor_label);
1371 }
1372 std::string artdaq::xmlrpc_commander::send_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp)
1373 {
1374  return send_command_("init", ps, timeout, timestamp);
1375 }
1376 std::string artdaq::xmlrpc_commander::send_soft_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp)
1377 {
1378  return send_command_("soft_init", ps, timeout, timestamp);
1379 }
1380 std::string xmlrpc_commander::send_reinit(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp)
1381 {
1382  return send_command_("reinit", ps, timeout, timestamp);
1383 }
1384 std::string xmlrpc_commander::send_start(art::RunID run, uint64_t timeout, uint64_t timestamp)
1385 {
1386  return send_command_("start", run, timeout, timestamp);
1387 }
1388 std::string xmlrpc_commander::send_pause(uint64_t timeout, uint64_t timestamp)
1389 {
1390  return send_command_("pause", timeout, timestamp);
1391 }
1392 std::string xmlrpc_commander::send_resume(uint64_t timeout, uint64_t timestamp)
1393 {
1394  return send_command_("resume", timeout, timestamp);
1395 }
1396 std::string xmlrpc_commander::send_stop(uint64_t timeout, uint64_t timestamp)
1397 {
1398  return send_command_("stop", timeout, timestamp);
1399 }
1400 std::string xmlrpc_commander::send_shutdown(uint64_t timeout)
1401 {
1402  return send_command_("shutdown", timeout);
1403 }
1405 {
1406  return send_command_("status");
1407 }
1408 std::string xmlrpc_commander::send_report(std::string what)
1409 {
1410  return send_command_("report", what);
1411 }
1413 {
1414  return send_command_("legal_commands");
1415 }
1416 std::string xmlrpc_commander::send_trace_get(std::string name)
1417 {
1418  return send_command_("trace_get", name);
1419 }
1420 std::string xmlrpc_commander::send_trace_set(std::string name, std::string type, std::string mask)
1421 {
1422  return send_command_("trace_set", name, type, mask);
1423 }
1424 std::string xmlrpc_commander::send_meta_command(std::string command, std::string arg)
1425 {
1426  return send_command_("meta_command", command, arg);
1427 }
1428 std::string xmlrpc_commander::send_rollover_subrun(uint64_t when, uint32_t sr)
1429 {
1430  return send_command_("rollover_subrun", when, sr);
1431 }
1432 } // namespace artdaq
1433 
1434 DEFINE_ARTDAQ_COMMANDER(artdaq::xmlrpc_commander)
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:499
std::string send_rollover_subrun(uint64_t seq, uint32_t subrunNumber) override
Send a send_rollover_subrun command over XMLRPC
This interface defines the functions used to transfer data between artdaq applications.
cmd_(xmlrpc_commander &c, const std::string &signature, const std::string &description)
cmd_ Constructor
static const uint64_t defaultTimeout
std::string send_trace_get(std::string name) override
Send an send_trace_get command over XMLRPC
std::string send_unregister_monitor(std::string monitor_label) override
Send an unregister_monitor command over XMLRPC
std::string send_register_monitor(std::string monitor_fhicl) override
Send a register_monitor command over XMLRPC
virtual std::string report(std::string const &) const
Default report implementation returns current report_string.
Definition: Commandable.hh:121
Commandable is the base class for all artdaq components which implement the artdaq state machine...
Definition: Commandable.hh:20
legal_commands_(xmlrpc_commander &c)
legal_commands_ Constructor
virtual bool do_clear_config_archive()
Clears the configuration archive list.
Definition: Commandable.cc:505
xmlrpc_commander(fhicl::ParameterSet ps, artdaq::Commandable &commandable)
xmlrpc_commander Constructor
Command class representing a start transition.
rollover_subrun_(xmlrpc_commander &c)
shutdown_ Constructor
status_ Command class
report_ Command class
std::string send_stop(uint64_t timeout, uint64_t timestamp) override
Send a stop command over XMLRPC
virtual std::string clear_config_archive()
Using the transport mechanism, send a clear_config_archive command
virtual std::string unregister_monitor(std::string const &)
Perform the unregister_monitor action.
Definition: Commandable.hh:150
meta_command_ Command class
std::string send_status() override
Send a status command over XMLRPC
std::string send_legal_commands() override
Send a legal_commands command over XMLRPC
The xmlrpc_commander class serves as the XMLRPC server run in each artdaq application.
static const uint64_t defaultTimestamp
static const uint32_t defaultSubrunNumber
Default subrun number for command.
std::string send_meta_command(std::string command, std::string argument) override
Send an send_meta_command command over XMLRPC
The &quot;cmd_&quot; class serves as the base class for all artdaq&#39;s XML-RPC commands.
trace_set_(xmlrpc_commander &c)
unregister_monitor_ Constructor
shutdown_ Command class
void run_server() override
Run the XMLRPC server.
meta_command_(xmlrpc_commander &c)
meta_command_ Constructor
std::unique_ptr< xmlrpc_c::serverAbyss > server
XMLRPC server.
std::string status() const
Returns the current state of the Commandable.
Definition: Commandable.cc:272
std::string send_shutdown(uint64_t timeout) override
Send a shutdown command over XMLRPC
std::string send_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp) override
Send an init command over XMLRPC
std::string exception_msg(const std::runtime_error &er, const std::string &helpText="execute request")
Write an exception message.
static const uint64_t defaultSequenceID
Default Sequence ID for command.
add_config_archive_entry_(xmlrpc_commander &c)
add_config_archive_entry_ Constructor
virtual std::string register_monitor(fhicl::ParameterSet const &)
Perform the register_monitor action.
Definition: Commandable.hh:139
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:486
virtual bool do_trace_set(std::string const &name, std::string const &type, std::string const &mask_in_string_form)
Set the given TRACE mask for the given TRACE name.
Definition: Commandable.cc:433
register_monitor_ Command class
add_config_archive_entry_ Command class
legal_commands_ Command class
std::string send_pause(uint64_t timeout, uint64_t timestamp) override
Send a pause command over XMLRPC
artdaq::Commandable & _commandable
Reference to the Commandable that this Commander Commands.
std::string send_trace_set(std::string name, std::string type, std::string mask) override
Send an send_trace_msgfacility_set command over XMLRPC
xmlrpc_commander & _c
The xmlrpc_commander instance that the command will be sent to.
std::string send_start(art::RunID runNumber, uint64_t timeout, uint64_t timestamp) override
Send a start command over XMLRPC
clear_config_archive_ Command class
trace_get_ Command class
std::string send_soft_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp) override
Send a soft_init command over XMLRPC
status_(xmlrpc_commander &c)
status_ Constructor
clear_config_archive_(xmlrpc_commander &c)
clear_config_archive_ Constructor
virtual std::string add_config_archive_entry(std::string key, std::string value)
Using the transport mechanism, send an add_config_archive_entry command
virtual bool execute_(const xmlrpc_c::paramList &, xmlrpc_c::value *const retvalP)=0
&quot;execute_&quot; is a wrapper function around the call to the commandable object&#39;s function ...
Wrapper for XMLRPC environment construction/destruction
std::timed_mutex mutex_
XMLRPC mutex.
register_monitor_(xmlrpc_commander &c)
register_monitor_ Constructor
static const uint64_t defaultTimeout
unregister_monitor_(xmlrpc_commander &c)
unregister_monitor_ Constructor
void execute(const xmlrpc_c::paramList &paramList, xmlrpc_c::value *const retvalP) final
Execute trhe command with the given parameters.
shutdown_(xmlrpc_commander &c)
shutdown_ Constructor
std::vector< std::string > legal_commands() const
Get the legal transition commands from the current state.
Definition: Commandable.cc:285
rollover_subrun_ Command class
std::string send_resume(uint64_t timeout, uint64_t timestamp) override
Send a resume command over XMLRPC
bool start(art::RunID id, uint64_t timeout, uint64_t timestamp)
Processes the start transition.
Definition: Commandable.cc:59
report_(xmlrpc_commander &c)
report_ Constructor
trace_set_ Command class
std::string send_report(std::string which) override
Send a report command over XMLRPC
start_(xmlrpc_commander &c)
start_ Command (cmd_ derived class) Constructor
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
trace_get_(xmlrpc_commander &c)
trace_msgfacility_set_ Constructor
std::string send_reinit(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp) override
Send a reinit command over XMLRPC
std::atomic< bool > running_
Whether the server is running and able to respond to requests.
virtual bool do_rollover_subrun(uint64_t eventNum, uint32_t subrunNum)
Perform the rollover_subrun transition.
Definition: Commandable.cc:492
unregister_monitor_ Command class
T getParam(const xmlrpc_c::paramList &paramList, int index)
Get a parameter from the parameter list.
bool shutdown(uint64_t timeout)
Processes the shutdown transition.
Definition: Commandable.cc:166