otsdaq  3.10.00
ARTDAQSupervisor.hh
1 #ifndef _ots_ARTDAQSupervisor_h
2 #define _ots_ARTDAQSupervisor_h
3 
4 #if __cplusplus > 201402L
5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Wregister"
7 #include <Python.h>
8 #pragma GCC diagnostic pop
9 #else
10 #include <Python.h>
11 #endif
12 
13 #include <mutex>
14 #include <set>
15 #include <thread>
16 
17 #include "artdaq/ExternalComms/CommanderInterface.hh"
18 #include "otsdaq/CoreSupervisors/CoreSupervisorBase.h"
19 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
20 
21 namespace ots
22 {
26 {
27  public:
28  XDAQ_INSTANTIATOR();
29 
31  {
32  std::string label;
33  std::string host;
34  int port;
35  int subsystem;
36  int rank;
37  std::string state;
38  };
39 
40  ARTDAQSupervisor(xdaq::ApplicationStub* s);
41  virtual ~ARTDAQSupervisor(void);
42 
43  void init(void);
44  void destroy(void);
45 
46  virtual void transitionConfiguring(toolbox::Event::Reference event) override;
47  virtual void transitionHalting(toolbox::Event::Reference event) override;
48  virtual void transitionInitializing(toolbox::Event::Reference event) override;
49  virtual void transitionPausing(toolbox::Event::Reference event) override;
50  virtual void transitionResuming(toolbox::Event::Reference event) override;
51  virtual void transitionStarting(toolbox::Event::Reference event) override;
52  virtual void transitionStopping(toolbox::Event::Reference event) override;
53  virtual void enteringError(toolbox::Event::Reference event) override;
54 
55  void request(const std::string& requestType,
56  cgicc::Cgicc& cgiIn,
57  HttpXmlDocument& xmlOut,
58  const WebUsers::RequestUserInfo& userInfo) override;
59 
60  virtual std::vector<SupervisorInfo::SubappInfo> getSubappInfo(void) override;
61  virtual std::string getStatusProgressDetail(void) override
62  {
63  if(!theStateMachine_.isInTransition() &&
64  (theStateMachine_.getCurrentStateName() ==
65  RunControlStateMachine::HALTED_STATE_NAME ||
66  theStateMachine_.getCurrentStateName() ==
67  RunControlStateMachine::INITIAL_STATE_NAME))
69 
70  std::lock_guard<std::mutex> lk(thread_mutex_);
71  __COUTVS__(20, thread_progress_message_);
72  return thread_progress_message_;
73  } //end getStatusProgressDetail()
74 
75  std::list<
76  std::pair<DAQInterfaceProcessInfo, std::unique_ptr<artdaq::CommanderInterface>>>
77  makeCommandersFromProcessInfo();
78 
79  // Hostnames of all enabled artdaq processes from the active configuration.
80  // Reflects the configuration's intended deployment (works even when
81  // DAQInterface is not running). Note: config does NOT carry the runtime
82  // xmlrpc commander ports -- this is for host discovery only.
83  std::set<std::string> getConfiguredArtdaqHosts(void);
84 
85  static std::list<std::string> tokenize_(std::string const& input);
86 
87  private:
88  void forceSupervisorPropertyValues(void) override;
89  void initArtdaqSystemVariables();
90  void saveArtdaqSystemVariables();
91  void loadArtdaqSystemVariables();
92  std::string getServiceDataFilePath() const;
93 
94  static const std::string ARTDAQ_SYSVAR_NAMESPACE;
95 
96  void configuringThread(void);
97  void startingThread(void);
98 
100  struct PyObjectGuard
101  {
102  PyObject* obj;
103  explicit PyObjectGuard(PyObject* o)
104  : obj(o) {}
105  ~PyObjectGuard()
106  {
107  if(obj)
108  Py_DECREF(obj);
109  }
110  PyObjectGuard(const PyObjectGuard&) = delete;
111  PyObjectGuard& operator=(const PyObjectGuard&) = delete;
112  PyObject* get() const { return obj; }
113  };
114 
115  PyObject *daqinterface_ptr_, *stringIO_out_,
116  *stringIO_err_; //stringIO_err_ not needed with new Tee Buffer solution
117  std::recursive_mutex daqinterface_pythonMutex_;
118  std::mutex daqinterface_statusMutex_;
119  std::string daqinterface_status_;
120  int partition_;
121  std::string daqinterface_state_;
122  std::unique_ptr<std::thread> runner_thread_;
123  std::atomic<bool> runner_running_;
124 
125  std::mutex thread_mutex_;
126  ProgressBar thread_progress_bar_;
127  std::string thread_progress_message_;
128  std::string thread_error_message_;
129  int last_thread_progress_read_;
130  time_t last_thread_progress_update_;
131  std::map<std::string, std::string> label_to_proc_type_map_;
132 
133  unsigned int cachedMinReadyForEventGenerationStartIteration_ = 0;
134 
135  std::string capturePyErr(std::string label = "");
136  bool checkPythonError(
137  PyObject* result); // Check if Python call failed (returns true on error)
138  std::string captureStderrAndStdout_(std::string label = "");
139  void getDAQState_(void);
140  std::string getProcessInfo_(void);
141  std::string artdaqStateToOtsState(std::string state);
142  std::string labelToProcType_(std::string label);
143  std::list<DAQInterfaceProcessInfo> getAndParseProcessInfo_(void);
144  void daqinterfaceRunner_(void);
145  void stop_runner_(void);
146  void start_runner_(void);
147  void set_thread_message_(std::string msg)
148  {
149  std::lock_guard<std::mutex> lk(thread_mutex_);
150  thread_progress_message_ = msg;
151  }
152 };
153 
154 } // namespace ots
155 
156 #endif
void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
virtual void transitionHalting(toolbox::Event::Reference event) override
virtual void transitionInitializing(toolbox::Event::Reference event) override
virtual std::string getStatusProgressDetail(void) override
virtual std::string getStatusProgressDetail(void)
defines used also by OtsConfigurationWizardSupervisor