Line data Source code
1 : #ifndef artdaq_Application_Commandable_hh
2 : #define artdaq_Application_Commandable_hh
3 :
4 : #include <mutex>
5 : #include <string>
6 : #include <vector>
7 :
8 : #include "canvas/Persistency/Provenance/RunID.h"
9 : namespace fhicl {
10 : class ParameterSet;
11 : }
12 :
13 : #include "artdaq/Application/detail/Commandable_sm.h" // must be included after others
14 :
15 : namespace artdaq {
16 : class Commandable;
17 : }
18 :
19 : /**
20 : * \brief Commandable is the base class for all artdaq components which implement the artdaq state machine
21 : */
22 : class artdaq::Commandable
23 : {
24 : public:
25 : /**
26 : * Default constructor.
27 : */
28 : Commandable();
29 :
30 : /**
31 : * \brief Copy Constructor is deleted
32 : */
33 : Commandable(Commandable const&) = delete;
34 :
35 : /**
36 : * \brief Default Destructor
37 : */
38 2 : virtual ~Commandable() = default;
39 :
40 : /**
41 : * \brief Copy Assignment operator is deleted
42 : * \return Commandable copy
43 : */
44 : Commandable& operator=(Commandable const&) = delete;
45 :
46 : Commandable(Commandable&&) = delete; ///< Move Constructor is deleted
47 : Commandable& operator=(Commandable&&) = delete; ///< Move Assignment Operator is deleted
48 :
49 : /**
50 : * \brief Processes the initialize request
51 : * \param pset ParameterSet used to configure the Commandable
52 : * \param timeout Timeout for init step
53 : * \param timestamp Timestamp of init step
54 : * \return Whether the transition was successful
55 : */
56 : bool initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp);
57 :
58 : /**
59 : * \brief Processes the start transition
60 : * \param id Run number of new run
61 : * \param timeout Timeout for transition
62 : * \param timestamp Timestamp of transition
63 : * \return Whether the transition was successful
64 : */
65 : bool start(art::RunID id, uint64_t timeout, uint64_t timestamp);
66 :
67 : /**
68 : * \brief Processes the stop transition
69 : * \param timeout Timeout for transition
70 : * \param timestamp Timestamp of transition
71 : * \return Whether the transition was successful
72 : */
73 : bool stop(uint64_t timeout, uint64_t timestamp);
74 :
75 : /**
76 : * \brief Processes the pause transition
77 : * \param timeout Timeout for transition
78 : * \param timestamp Timestamp of transition
79 : * \return Whether the transition was successful
80 : */
81 : bool pause(uint64_t timeout, uint64_t timestamp);
82 :
83 : /**
84 : * \brief Processes the resume transition
85 : * \param timeout Timeout for transition
86 : * \param timestamp Timestamp of transition
87 : * \return Whether the transition was successful
88 : */
89 : bool resume(uint64_t timeout, uint64_t timestamp);
90 :
91 : /**
92 : * \brief Processes the shutdown transition
93 : * \param timeout Timeout for transition
94 : * \return Whether the transition was successful
95 : */
96 : bool shutdown(uint64_t timeout);
97 :
98 : /**
99 : * \brief Processes the soft-initialize request
100 : * \param pset ParameterSet used to configure the Commandable
101 : * \param timeout Timeout for init step
102 : * \param timestamp Timestamp of init step
103 : * \return Whether the transition was successful
104 : */
105 : bool soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp);
106 :
107 : /**
108 : * \brief Processes the reinitialize request
109 : * \param pset ParameterSet used to configure the Commandable
110 : * \param timeout Timeout for init step
111 : * \param timestamp Timestamp of init step
112 : * \return Whether the transition was successful
113 : */
114 : bool reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp);
115 :
116 : /**
117 : * \brief Actions taken when the in_run_failure state is set
118 : * \return Whether the notification was properly processed
119 : */
120 : bool in_run_failure();
121 :
122 : /**
123 : * \brief Default report implementation returns current report_string
124 : * \return Current report_string (may be set by derived classes)
125 : */
126 0 : virtual std::string report(std::string const&) const
127 : {
128 0 : std::lock_guard<std::mutex> lk(primary_mutex_);
129 0 : return report_string_;
130 0 : }
131 :
132 : /**
133 : * \brief Returns the current state of the Commandable
134 : * \return The current state of the Commandable
135 : */
136 : std::string status() const;
137 :
138 : /**
139 : * \brief Perform the register_monitor action.
140 : * \return A report on the status of the command
141 : *
142 : * This function is a No-Op. Derived classes should override it.
143 : */
144 0 : virtual std::string register_monitor(fhicl::ParameterSet const&)
145 : {
146 0 : return "This string is returned from Commandable::register_monitor; register_monitor should either be overridden in a derived class or this process should not have been sent the register_monitor call";
147 : }
148 :
149 : /**
150 : * \brief Perform the unregister_monitor action.
151 : * \return A report on the status of the command
152 : *
153 : * This function is a No-Op. Derived classes should override it.
154 : */
155 0 : virtual std::string unregister_monitor(std::string const&)
156 : {
157 0 : return "This string is returned from Commandable::unregister_monitor; unregister_monitor should either be overridden in a derived class or this process should not have been sent the unregister_monitor call";
158 : }
159 :
160 : /**
161 : * \brief Get the legal transition commands from the current state
162 : * \return A list of legal transitions from the current state
163 : */
164 : std::vector<std::string> legal_commands() const;
165 :
166 : // these methods provide the operations that are used by the state machine
167 : /**
168 : * \brief Perform the initialize transition.
169 : * \return Whether the transition succeeded
170 : *
171 : * This function is a No-Op. Derived classes should override it.
172 : */
173 : virtual bool do_initialize(fhicl::ParameterSet const&, uint64_t, uint64_t);
174 :
175 : /**
176 : * \brief Perform the start transition.
177 : * \return Whether the transition succeeded
178 : *
179 : * This function is a No-Op. Derived classes should override it.
180 : */
181 : virtual bool do_start(art::RunID, uint64_t, uint64_t);
182 :
183 : /**
184 : * \brief Perform the stop transition.
185 : * \return Whether the transition succeeded
186 : *
187 : * This function is a No-Op. Derived classes should override it.
188 : */
189 : virtual bool do_stop(uint64_t, uint64_t);
190 :
191 : /**
192 : * \brief Perform the pause transition.
193 : * \return Whether the transition succeeded
194 : *
195 : * This function is a No-Op. Derived classes should override it.
196 : */
197 : virtual bool do_pause(uint64_t, uint64_t);
198 :
199 : /**
200 : * \brief Perform the resume transition.
201 : * \return Whether the transition succeeded
202 : *
203 : * This function is a No-Op. Derived classes should override it.
204 : */
205 : virtual bool do_resume(uint64_t, uint64_t);
206 :
207 : /**
208 : * \brief Perform the shutdown transition.
209 : * \return Whether the transition succeeded
210 : *
211 : * This function is a No-Op. Derived classes should override it.
212 : */
213 : virtual bool do_shutdown(uint64_t);
214 :
215 : /**
216 : * \brief Perform the reinitialize transition.
217 : * \return Whether the transition succeeded
218 : *
219 : * This function is a No-Op. Derived classes should override it.
220 : */
221 : virtual bool do_reinitialize(fhicl::ParameterSet const&, uint64_t, uint64_t);
222 :
223 : /**
224 : * \brief Perform the soft_initialize transition.
225 : * \return Whether the transition succeeded
226 : *
227 : * This function is a No-Op. Derived classes should override it.
228 : */
229 : virtual bool do_soft_initialize(fhicl::ParameterSet const&, uint64_t, uint64_t);
230 :
231 : /**
232 : * \brief Perform the rollover_subrun transition.
233 : * \param eventNum Sequence ID of boundary
234 : * \param subrunNum New Subrun Number
235 : * \return Whether the transition succeeded
236 : */
237 : virtual bool do_rollover_subrun(uint64_t eventNum, uint32_t subrunNum);
238 :
239 : /**
240 : * \brief This function is called when an attempt is made to call an illegal transition
241 : * \param trans The transition that was attempted
242 : */
243 : virtual void badTransition(const std::string& trans);
244 :
245 : /**
246 : * \brief Perform actions upon entering the Booted state
247 : *
248 : * This function is a No-Op. Derived classes should override it.
249 : */
250 : virtual void BootedEnter();
251 :
252 : /**
253 : * \brief Perform actions upon leaving the InRun state
254 : *
255 : * This function is a No-Op. Derived classes should override it.
256 : */
257 : virtual void InRunExit();
258 :
259 : /**
260 : * \brief Get the TRACE mask for the given TRACE name
261 : * If name is "ALL", then all TRACE masks will be printed
262 : *
263 : * This function is implemented in Commandable, derived classes may override if necessary.
264 : * \param name TRACE name to print mask for. "ALL" prints all TRACE masks
265 : * \return TRACE mask of the given TRACE name
266 : */
267 : virtual std::string do_trace_get(std::string const& name);
268 :
269 : /**
270 : * \brief Set the given TRACE mask for the given TRACE name
271 : *
272 : * This function is implemented in Commandable, derived classes may override if necessary.
273 : * \param name Name of the TRACE level to set mask for
274 : * \param type Type of TRACE mask to set (either M, S, or T)
275 : * \param mask_in_string_form Mask to set
276 : * \return Whether the command succeeded (always true)
277 : */
278 : virtual bool do_trace_set(std::string const& name, std::string const& type, std::string const& mask_in_string_form);
279 :
280 : /**
281 : * \brief Run a module-defined command with the given parameter string
282 : *
283 : * This function is a No-Op. Derived classes should override it.
284 : * \param cmd Name of the command to run (implementation-defined)
285 : * \param args Any arguments for the command (implementation-defined)
286 : * \return Whether the command succeeded (always true)
287 : */
288 : virtual bool do_meta_command(std::string const& cmd, std::string const& args);
289 :
290 : /**
291 : * \brief Add the specified key-value pair to the configuration archive list
292 : * \return Whether the command succeeded (always true)
293 : *
294 : * This function is a No-Op. Derived classes should override it.
295 : */
296 : virtual bool do_add_config_archive_entry(std::string const&, std::string const&);
297 :
298 : /**
299 : * \brief Clears the configuration archive list
300 : * \return Whether the command succeeded (always true)
301 : *
302 : * This function is a No-Op. Derived classes should override it.
303 : */
304 : virtual bool do_clear_config_archive();
305 :
306 : protected:
307 : /**
308 : * \brief Return the name of the current state
309 : * \return The name of the current state
310 : */
311 : std::string current_state() const;
312 :
313 : CommandableContext fsm_; ///< The generated State Machine (using smc_compiler)
314 : bool external_request_status_; ///< Whether the last command succeeded
315 : std::string report_string_; ///< Status information about the last command
316 :
317 : private:
318 : // 06-May-2015, KAB: added a mutex to be used in avoiding problems when
319 : // requests are sent to a Commandable object from different threads. The
320 : // reason that we're doing this now is that we've added the in_run_failure()
321 : // transition that will generally be called from inside the Application.
322 : // Prior to this, the only way that transitions were requested was via
323 : // external XMLRPC commands, and those were presumed to be called one
324 : // at a time. The use of scoped locks based on the mutex will prevent
325 : // the in_run_failure() transition from being called at the same time as
326 : // an externally requested transition. We only lock the methods that
327 : // are externally called.
328 : mutable std::mutex primary_mutex_;
329 : };
330 :
331 : #endif /* artdaq_Application_Commandable_hh */
|