artdaq  v3_08_00
CommandableFragmentGenerator.hh
1 #ifndef artdaq_Application_CommandableFragmentGenerator_hh
2 #define artdaq_Application_CommandableFragmentGenerator_hh
3 
4 // Socket Includes
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <sys/socket.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10 
11 #include <array>
12 #include <atomic>
13 #include <chrono>
14 #include <condition_variable>
15 #include <list>
16 #include <mutex>
17 #include <queue>
18 
19 #include "fhiclcpp/ParameterSet.h"
20 #include "fhiclcpp/fwd.h"
21 
22 #include "artdaq-core/Data/Fragment.hh"
23 #include "artdaq-core/Generators/FragmentGenerator.hh"
24 #include "artdaq-utilities/Plugins/MetricManager.hh"
25 #include "artdaq/DAQdata/Globals.hh"
26 #include "artdaq/DAQrate/RequestReceiver.hh"
27 
28 namespace artdaq {
32 enum class RequestMode
33 {
34  Single,
35  Buffer,
36  Window,
37  SequenceID,
38  Ignored
39 };
40 
83 class CommandableFragmentGenerator : public FragmentGenerator
84 {
85 public:
89  struct Config
90  {
92  fhicl::Atom<std::string> generator_type{fhicl::Name{"generator"}, fhicl::Comment{"Name of the CommandableFragmentGenerator plugin to load"}};
94  fhicl::Atom<Fragment::timestamp_t> request_window_offset{fhicl::Name{"request_window_offset"}, fhicl::Comment{"Request messages contain a timestamp. For Window request mode, start the window this far before the timestamp in the request"}, 0};
96  fhicl::Atom<Fragment::timestamp_t> request_window_width{fhicl::Name{"request_window_width"}, fhicl::Comment{"For Window request mode, the window will be timestamp - offset to timestamp - offset + width"}, 0};
98  fhicl::Atom<Fragment::timestamp_t> stale_request_timeout{fhicl::Name{"stale_request_timeout"}, fhicl::Comment{"Fragments stored in the fragment generator which are older than the newest stored fragment by at least stale_request_timeout units of request timestamp ticks will get discarded"}, 0xFFFFFFFF};
100  fhicl::Atom<bool> buffer_mode_keep_latest{fhicl::Name{"buffer_mode_keep_latest"}, fhicl::Comment{"Keep the latest Fragment when running in Buffer mode, so that each response has at least one Fragment (Fragment will be discarded if new data arrives before next request)"}, false};
102  fhicl::Atom<Fragment::type_t> expected_fragment_type{fhicl::Name{"expected_fragment_type"}, fhicl::Comment{"The type of Fragments this CFG will be generating. \"Empty\" will auto-detect type based on Fragments generated."}, Fragment::type_t(Fragment::EmptyFragmentType)};
104  fhicl::Atom<bool> request_windows_are_unique{fhicl::Name{"request_windows_are_unique"}, fhicl::Comment{"Whether Fragments should be removed from the buffer when matched to a request window"}, true};
106  fhicl::Atom<size_t> missing_request_window_timeout_us{fhicl::Name{"missing_request_window_timeout_us"}, fhicl::Comment{"How long to track missing requests in the \"out - of - order Windows\" list"}, 5000000};
108  fhicl::Atom<size_t> window_close_timeout_us{fhicl::Name{"window_close_timeout_us"}, fhicl::Comment{"How long to wait for the end of the data buffer to pass the end of a request window (measured from the time the request was received)"}, 2000000};
110  fhicl::Atom<bool> separate_data_thread{fhicl::Name{"separate_data_thread"}, fhicl::Comment{"Whether data collection should proceed on its own thread. Required for all data request processing"}, false};
112  fhicl::Atom<bool> circular_buffer_mode{fhicl::Name{"circular_buffer_mode"}, fhicl::Comment{"Whether the data buffer should be treated as a circular buffer on the input side (i.e. old fragments are automatically discarded when the buffer is full to always call getNext_)."}, false};
114  fhicl::Atom<size_t> sleep_on_no_data_us{fhicl::Name{"sleep_on_no_data_us"}, fhicl::Comment{"How long to sleep after calling getNext_ if no data is returned"}, 0};
116  fhicl::Atom<int> data_buffer_depth_fragments{fhicl::Name{"data_buffer_depth_fragments"}, fhicl::Comment{"The max fragments which can be stored before dropping occurs"}, 1000};
118  fhicl::Atom<size_t> data_buffer_depth_mb{fhicl::Name{"data_buffer_depth_mb"}, fhicl::Comment{"The max cumulative size in megabytes of the fragments which can be stored before dropping occurs"}, 1000};
120  fhicl::Atom<bool> separate_monitoring_thread{fhicl::Name{"separate_monitoring_thread"}, fhicl::Comment{"Whether a thread that calls the checkHWStatus_ method should be created"}, false};
122  fhicl::Atom<int64_t> hardware_poll_interval_us{fhicl::Name{"hardware_poll_interval_us"}, fhicl::Comment{"If a separate monitoring thread is used, how often should it call checkHWStatus_"}, 0};
124  fhicl::Atom<int> board_id{fhicl::Name{"board_id"}, fhicl::Comment{"The identification number for this CommandableFragmentGenerator"}};
127  fhicl::Sequence<Fragment::fragment_id_t> fragment_ids{fhicl::Name("fragment_ids"), fhicl::Comment("A list of Fragment IDs created by this CommandableFragmentGenerator")};
130  fhicl::Atom<int> fragment_id{fhicl::Name{"fragment_id"}, fhicl::Comment{"The Fragment ID created by this CommandableFragmentGenerator"}, -99};
132  fhicl::Atom<int> sleep_on_stop_us{fhicl::Name{"sleep_on_stop_us"}, fhicl::Comment{"How long to sleep before returning when stop transition is called"}, 0};
141  fhicl::Atom<std::string> request_mode{fhicl::Name{"request_mode"}, fhicl::Comment{"The mode by which the CommandableFragmentGenerator will process reqeusts"}, "ignored"};
142  fhicl::TableFragment<artdaq::RequestReceiver::Config> receiverConfig;
143  };
145  using Parameters = fhicl::WrappedTable<Config>;
146 
151  explicit CommandableFragmentGenerator(const fhicl::ParameterSet& ps);
152 
159 
166  void joinThreads();
167 
173  bool getNext(FragmentPtrs& output) override final;
174 
180  void applyRequestsIgnoredMode(artdaq::FragmentPtrs& frags);
181 
187  void applyRequestsSingleMode(artdaq::FragmentPtrs& frags);
188 
194  void applyRequestsBufferMode(artdaq::FragmentPtrs& frags);
195 
201  void applyRequestsWindowMode(artdaq::FragmentPtrs& frags);
202 
208  void applyRequestsSequenceIDMode(artdaq::FragmentPtrs& frags);
209 
216  void applyRequestsWindowMode_CheckAndFillDataBuffer(artdaq::FragmentPtrs& frags, artdaq::Fragment::fragment_id_t id, artdaq::Fragment::sequence_id_t seq, artdaq::Fragment::timestamp_t ts);
217 
223  bool applyRequests(FragmentPtrs& frags);
224 
233  bool sendEmptyFragment(FragmentPtrs& frags, size_t sequenceId, Fragment::fragment_id_t fragmentId, std::string desc);
234 
241  void sendEmptyFragments(FragmentPtrs& frags, std::map<Fragment::sequence_id_t, Fragment::timestamp_t>& requests);
242 
247  void checkSentWindows(Fragment::sequence_id_t seq);
248 
252  void startDataThread();
253 
257  void startMonitoringThread();
258 
263  void getDataLoop();
264 
270  bool waitForDataBufferReady(Fragment::fragment_id_t id);
271 
277  bool dataBufferIsTooLarge(Fragment::fragment_id_t id);
278 
283  void getDataBufferStats(Fragment::fragment_id_t id);
284 
289  {
290  for (auto& id : dataBuffers_) getDataBufferStats(id.first);
291  }
292 
299  void checkDataBuffer(Fragment::fragment_id_t id);
300 
305  {
306  for (auto& id : dataBuffers_) checkDataBuffer(id.first);
307  }
308 
316  std::map<Fragment::sequence_id_t, std::chrono::steady_clock::time_point> GetSentWindowList(Fragment::fragment_id_t id)
317  {
318  if (!dataBuffers_.count(id))
319  {
320  throw cet::exception("DataBufferError") << "Error in CommandableFragmentGenerator: Cannot get Sent Windows for ID " << id << " because it does not exist!";
321  }
322  return dataBuffers_[id].WindowsSent;
323  }
324 
328  void getMonitoringDataLoop();
329 
334  std::vector<Fragment::fragment_id_t> fragmentIDs() override
335  {
336  std::vector<Fragment::fragment_id_t> output;
337 
338  for (auto& id : dataBuffers_)
339  {
340  output.push_back(id.first);
341  }
342 
343  return output;
344  }
345 
350  size_t ev_counter() const { return ev_counter_.load(); }
351 
356  RequestMode request_mode() const { return mode_; }
357 
358  //
359  // State-machine related interface below.
360  //
361 
376  void StartCmd(int run, uint64_t timeout, uint64_t timestamp);
377 
387  void StopCmd(uint64_t timeout, uint64_t timestamp);
388 
398  void PauseCmd(uint64_t timeout, uint64_t timestamp);
399 
408  void ResumeCmd(uint64_t timeout, uint64_t timestamp);
409 
420  std::string ReportCmd(std::string const& which = "");
421 
426  virtual std::string metricsReportingInstanceName() const
427  {
428  return instance_name_for_metrics_;
429  }
430 
431  // The following functions are not yet implemented, and their
432  // signatures may be subject to change.
433 
434  // John F., 12/6/13 -- do we want Reset and Shutdown commands?
435  // Kurt B., 15-Feb-2014. For the moment, I suspect that we don't
436  // want a Shutdown command. FragmentGenerator instances are
437  // Constructed at Initialization time, and they are destructed
438  // at Shutdown time. So, any shutdown operations that need to be
439  // done should be put in the FragmentGenerator child class
440  // destructors. If we find that want shutdown (or initialization)
441  // operations that are different from destruction (construction),
442  // then we'll have to add InitCmd and ShutdownCmd methods.
443 
444  // virtual void ResetCmd() final {}
445  // virtual void ShutdownCmd() final {}
446 
451  bool exception() const { return exception_.load(); }
452 
459  virtual bool metaCommand(std::string const& command, std::string const& arg);
460 
461 protected:
462  // John F., 12/6/13 -- need to figure out which of these getter
463  // functions should be promoted to "public"
464 
465  // John F., 1/21/15 -- after more than a year, there hasn't been a
466  // single complaint that a CommandableFragmentGenerator-derived
467  // class hasn't allowed its users to access these quantities, so
468  // they're probably fine as is
469 
474  int run_number() const { return run_number_; }
479  int subrun_number() const { return subrun_number_; }
484  uint64_t timeout() const { return timeout_; }
489  uint64_t timestamp() const { return timestamp_; }
490 
496  artdaq::Fragment::fragment_id_t fragment_id() const
497  {
498  if (dataBuffers_.size() > 1) throw cet::exception("FragmentID") << "fragment_id() was called, indicating that Fragment Generator was expecting one and only one Fragment ID, but " << dataBuffers_.size() << " were declared!";
499  return (*dataBuffers_.begin()).first;
500  }
501 
506  bool should_stop() const { return should_stop_.load(); }
507 
512  bool check_stop();
513 
518  int board_id() const { return board_id_; }
519 
526  size_t ev_counter_inc(size_t step = 1, bool force = false); // returns the prev value
527 
532  void set_exception(bool exception) { exception_.store(exception); }
533 
538  void metricsReportingInstanceName(std::string const& name)
539  {
540  instance_name_for_metrics_ = name;
541  }
542 
547  std::string printMode_();
548 
549  // John F., 12/10/13
550  // Is there a better way to handle mutex_ than leaving it a protected variable?
551 
552  // John F., 1/21/15
553  // Translation above is "should mutex_ be a private variable,
554  // accessible via a getter function". Probably, but at this point
555  // it's not worth breaking code by implementing this.
556 
557  std::mutex mutex_;
558 
564  {
565  size_t count = 0;
566  for (auto& id : dataBuffers_) count += id.second.DataBufferDepthFragments;
567  return count;
568  }
569 
574  std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> GetRequests() const
575  {
576  if (requestReceiver_ == nullptr) return std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t>();
577  return requestReceiver_->GetRequests();
578  }
579 
584  std::pair<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> GetNextRequest() const
585  {
586  if (requestReceiver_ == nullptr) return std::make_pair<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t>(0, 0);
587  return requestReceiver_->GetNextRequest();
588  }
589 
594  size_t GetCurrentRequestCount() const
595  {
596  if (requestReceiver_ == nullptr) return 0;
597  return requestReceiver_->size();
598  }
599 
600 private:
601  // FHiCL-configurable variables. Note that the C++ variable names
602  // are the FHiCL variable names with a "_" appended
603 
604  //Socket parameters
605  std::unique_ptr<RequestReceiver> requestReceiver_;
606 
607  RequestMode mode_;
608  bool bufferModeKeepLatest_;
609  Fragment::timestamp_t windowOffset_;
610  Fragment::timestamp_t windowWidth_;
611  Fragment::timestamp_t staleTimeout_;
612  Fragment::type_t expectedType_;
613  bool uniqueWindows_;
614  size_t missing_request_window_timeout_us_;
615  size_t window_close_timeout_us_;
616 
617  bool useDataThread_;
618  bool circularDataBufferMode_;
619  size_t sleep_on_no_data_us_;
620  std::atomic<bool> data_thread_running_;
621  boost::thread dataThread_;
622 
623  std::condition_variable dataCondition_;
624  int maxDataBufferDepthFragments_;
625  size_t maxDataBufferDepthBytes_;
626 
627  bool useMonitoringThread_;
628  boost::thread monitoringThread_;
629  int64_t monitoringInterval_; // Microseconds
630  std::chrono::steady_clock::time_point lastMonitoringCall_;
631  std::atomic<bool> isHardwareOK_;
632 
633  struct DataBuffer
634  {
635  std::atomic<int> DataBufferDepthFragments;
636  std::atomic<size_t> DataBufferDepthBytes;
637  std::map<Fragment::sequence_id_t, std::chrono::steady_clock::time_point> WindowsSent;
638  bool BufferFragmentKept;
639  Fragment::sequence_id_t HighestRequestSeen;
640  FragmentPtrs DataBuffer;
641  };
642 
643  std::mutex dataBuffersMutex_;
644  std::unordered_map<artdaq::Fragment::fragment_id_t, DataBuffer> dataBuffers_;
645 
646  // In order to support the state-machine related behavior, all
647  // CommandableFragmentGenerators must be able to remember a run number and a
648  // subrun number.
649  int run_number_, subrun_number_;
650 
651  // JCF, 8/28/14
652 
653  // Provide a user-adjustable timeout for the start transition
654  uint64_t timeout_;
655 
656  // JCF, 8/21/14
657 
658  // In response to a need to synchronize various components using
659  // different fragment generators in an experiment, keep a record
660  // of a timestamp (see Redmine Issue #6783 for more)
661 
662  uint64_t timestamp_;
663 
664  std::atomic<bool> should_stop_, exception_, force_stop_;
665  std::string latest_exception_report_;
666  std::atomic<size_t> ev_counter_;
667 
668  int board_id_;
669  std::string instance_name_for_metrics_;
670 
671  // Depending on what sleep_on_stop_us_ is set to, this gives the
672  // stopping thread the chance to gather the required lock
673 
674  int sleep_on_stop_us_;
675 
676 protected:
684  virtual bool getNext_(FragmentPtrs& output) = 0;
685 
692  virtual bool checkHWStatus_();
693 
694  //
695  // State-machine related implementor interface below.
696  //
697 
708  virtual void start() = 0;
709 
716  virtual void stopNoMutex() = 0;
717 
726  virtual void stop() = 0;
727 
732  virtual void pauseNoMutex();
733 
739  virtual void pause();
740 
744  virtual void resume();
745 
757  virtual std::string report();
758 
764  virtual std::string reportSpecific(std::string const& what);
765 };
766 } // namespace artdaq
767 
768 #endif /* artdaq_Application_CommandableFragmentGenerator_hh */
fhicl::Atom< Fragment::type_t > expected_fragment_type
&quot;expected_fragment_type&quot; (Default: 231, EmptyFragmentType) : The type of Fragments this CFG will be g...
fhicl::Atom< int > board_id
&quot;board_id&quot; (REQUIRED) : The identification number for this CommandableFragmentGenerator ...
CommandableFragmentGenerator(const fhicl::ParameterSet &ps)
CommandableFragmentGenerator Constructor.
void applyRequestsSingleMode(artdaq::FragmentPtrs &frags)
Create fragments using data buffer for request mode Single. Precondition: dataBufferMutex_ and reques...
int subrun_number() const
Get the current Subrun number.
size_t GetCurrentRequestCount() const
Get the number of requests currently stored in the Request Recevier
virtual void start()=0
If a CommandableFragmentGenerator subclass is reading from a file, and start() is called...
fhicl::Atom< int64_t > hardware_poll_interval_us
&quot;hardware_poll_interval_us&quot; (Default: 0) : If a separate monitoring thread is used, how often should it call checkHWStatus_
virtual bool checkHWStatus_()
Check any relavent hardware status registers. Return false if an error condition exists that should h...
virtual ~CommandableFragmentGenerator()
CommandableFragmentGenerator Destructor.
RequestMode
The RequestMode enumeration contains the possible ways which CommandableFragmentGenerator responds to...
void applyRequestsBufferMode(artdaq::FragmentPtrs &frags)
Create fragments using data buffer for request mode Buffer. Precondition: dataBufferMutex_ and reques...
bool exception() const
Get the current value of the exception flag.
void metricsReportingInstanceName(std::string const &name)
Sets the name for metrics reporting.
std::mutex mutex_
Mutex used to ensure that multiple transition commands do not run at the same time.
void getDataBufferStats(Fragment::fragment_id_t id)
Calculate the size of the dataBuffer and report appropriate metrics.
void getMonitoringDataLoop()
This function regularly calls checkHWStatus_(), and sets the isHardwareOK flag accordingly.
void startDataThread()
Function that launches the data thread (getDataLoop())
artdaq::Fragment::fragment_id_t fragment_id() const
Get the Fragment ID of this Fragment generator.
fhicl::TableFragment< artdaq::RequestReceiver::Config > receiverConfig
Configuration for the Request Receiver. See artdaq::RequestReceiver::Config.
std::string ReportCmd(std::string const &which="")
Get a report about a user-specified run-time quantity.
virtual bool metaCommand(std::string const &command, std::string const &arg)
The meta-command is used for implementing user-specific commands in a CommandableFragmentGenerator.
fhicl::Atom< Fragment::timestamp_t > stale_request_timeout
&quot;stale_request_timeout&quot; (Default: -1) : Fragments stored in the fragment generator which are older th...
void StopCmd(uint64_t timeout, uint64_t timestamp)
Stop the CommandableFragmentGenerator.
void getDataBuffersStats()
Calculate the size of all dataBuffers and report appropriate metrics.
void applyRequestsWindowMode_CheckAndFillDataBuffer(artdaq::FragmentPtrs &frags, artdaq::Fragment::fragment_id_t id, artdaq::Fragment::sequence_id_t seq, artdaq::Fragment::timestamp_t ts)
void checkSentWindows(Fragment::sequence_id_t seq)
Check the windows_sent_ooo_ map for sequence IDs that may be removed.
bool sendEmptyFragment(FragmentPtrs &frags, size_t sequenceId, Fragment::fragment_id_t fragmentId, std::string desc)
Send an EmptyFragmentType Fragment.
uint64_t timeout() const
Timeout of last command.
void applyRequestsWindowMode(artdaq::FragmentPtrs &frags)
Create fragments using data buffer for request mode Window. Precondition: dataBufferMutex_ and reques...
void StartCmd(int run, uint64_t timeout, uint64_t timestamp)
Start the CommandableFragmentGenerator.
virtual void pauseNoMutex()
On call to PauseCmd, pauseNoMutex() is called prior to PauseCmd acquiring the mutex ...
bool check_stop()
Routine used by applyRequests to make sure that all outstanding requests have been fulfilled before r...
void ResumeCmd(uint64_t timeout, uint64_t timestamp)
Resume the CommandableFragmentGenerator.
fhicl::Atom< bool > buffer_mode_keep_latest
&quot;buffer_mode_keep_latest&quot; (Default: false): Keep the latest Fragment when running in Buffer mode...
bool getNext(FragmentPtrs &output) overridefinal
getNext calls either applyRequests or getNext_ to get any data that is ready to be sent to the EventB...
size_t ev_counter_inc(size_t step=1, bool force=false)
Increment the event counter, if the current RequestMode allows it.
fhicl::Atom< int > data_buffer_depth_fragments
&quot;data_buffer_depth_fragments&quot; (Default: 1000) : The max fragments which can be stored before dropping...
fhicl::Atom< size_t > data_buffer_depth_mb
&quot;data_buffer_depth_mb&quot; (Default: 1000) : The max cumulative size in megabytes of the fragments which ...
std::map< Fragment::sequence_id_t, std::chrono::steady_clock::time_point > GetSentWindowList(Fragment::fragment_id_t id)
Get the map of Window-mode requests fulfilled by this Fragment Geneerator for the given Fragment ID...
bool applyRequests(FragmentPtrs &frags)
See if any requests have been received, and add the corresponding data Fragment objects to the output...
std::vector< Fragment::fragment_id_t > fragmentIDs() override
Get the list of Fragment IDs handled by this CommandableFragmentGenerator.
fhicl::Atom< int > sleep_on_stop_us
&quot;sleep_on_stop_us&quot; (Default: 0) : How long to sleep before returning when stop transition is called ...
void applyRequestsIgnoredMode(artdaq::FragmentPtrs &frags)
Create fragments using data buffer for request mode Ignored. Precondition: dataBufferMutex_ and reque...
fhicl::Atom< size_t > missing_request_window_timeout_us
&quot;missing_request_window_timeout_us&quot; (Default: 5000000) : How long to track missing requests in the &quot;o...
void PauseCmd(uint64_t timeout, uint64_t timestamp)
Pause the CommandableFragmentGenerator.
void getDataLoop()
When separate_data_thread is set to true, this loop repeatedly calls getNext_ and adds returned Fragm...
fhicl::Sequence< Fragment::fragment_id_t > fragment_ids
virtual std::string metricsReportingInstanceName() const
Get the name used when reporting metrics.
void sendEmptyFragments(FragmentPtrs &frags, std::map< Fragment::sequence_id_t, Fragment::timestamp_t > &requests)
This function is for Buffered and Single request modes, as they can only respond to one data request ...
bool should_stop() const
Get the current value of the should_stop flag.
size_t dataBufferFragmentCount_()
Get the total number of Fragments in all data buffers.
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
void checkDataBuffers()
Perform data buffer pruning operations for all buffers.
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
virtual bool getNext_(FragmentPtrs &output)=0
Obtain the next group of Fragments, if any are available. Return false if readout cannot continue...
fhicl::Atom< std::string > request_mode
&quot;request_mode&quot; (Deafult: Ignored) : The mode by which the CommandableFragmentGenerator will process r...
void startMonitoringThread()
Function that launches the monitoring thread (getMonitoringDataLoop())
fhicl::Atom< Fragment::timestamp_t > request_window_offset
&quot;request_window_offset&quot; (Default: 0) : Request messages contain a timestamp. For Window request mode...
virtual void pause()
If a CommandableFragmentGenerator subclass is reading from hardware, the implementation of pause() sh...
virtual void resume()
The subrun number will be incremented before a call to resume.
void applyRequestsSequenceIDMode(artdaq::FragmentPtrs &frags)
Create fragments using data buffer for request mode SequenceID. Precondition: dataBufferMutex_ and re...
size_t ev_counter() const
Get the current value of the event counter.
fhicl::Atom< bool > request_windows_are_unique
&quot;request_windows_are_unique&quot; (Default: true) : Whether Fragments should be removed from the buffer wh...
fhicl::Atom< size_t > window_close_timeout_us
&quot;window_close_timeout_us&quot; (Default: 2000000) : How long to wait for the end of the data buffer to pas...
fhicl::Atom< size_t > sleep_on_no_data_us
&quot;sleep_on_no_data_us&quot; (Default: 0 (no sleep)) : How long to sleep after calling getNext_ if no data i...
bool waitForDataBufferReady(Fragment::fragment_id_t id)
Wait for the data buffer to drain (dataBufferIsTooLarge returns false), periodically reporting status...
fhicl::Atom< Fragment::timestamp_t > request_window_width
&quot;request_window_width&quot; (Default: 0) : For Window request mode, the window will be timestamp - offset ...
virtual std::string report()
Let&#39;s say that the contract with the report() functions is that they return a non-empty string if the...
virtual void stopNoMutex()=0
On call to StopCmd, stopNoMutex() is called prior to StopCmd acquiring the mutex
fhicl::Atom< bool > separate_data_thread
&quot;separate_data_thread&quot; (Default: false) : Whether data collection should proceed on its own thread...
int board_id() const
Gets the current board_id.
std::string printMode_()
Return the string representation of the current RequestMode.
void set_exception(bool exception)
Control the exception flag.
RequestMode request_mode() const
Get the current request mode of the CommandableFragmentGenerator
uint64_t timestamp() const
Timestamp of last command.
void checkDataBuffer(Fragment::fragment_id_t id)
Perform data buffer pruning operations for the given buffer. If the RequestMode is Single...
fhicl::Atom< bool > circular_buffer_mode
&quot;circular_buffer_mode&quot; (Default: false) : Whether the data buffer should be treated as a circular buf...
Configuration of the CommandableFragmentGenerator. May be used for parameter validation ...
fhicl::Atom< std::string > generator_type
&quot;generator&quot; (REQUIRED) Name of the CommandableFragmentGenerator plugin to load
virtual void stop()=0
If a CommandableFragmentGenerator subclass is reading from a file, calling stop() should arrange that...
virtual std::string reportSpecific(std::string const &what)
Report the status of a specific quantity
bool dataBufferIsTooLarge(Fragment::fragment_id_t id)
Test the configured constraints on the data buffer.
std::pair< artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t > GetNextRequest() const
Get the next request (i.e. the request with the lowest sequence ID) to be handled by this Commandable...
int run_number() const
Get the current Run number.
std::map< artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t > GetRequests() const
Get the current requests being handled by this CommandableFragmentGenerator
fhicl::Atom< bool > separate_monitoring_thread
&quot;separate_monitoring_thread&quot; (Default: false) : Whether a thread that calls the checkHWStatus_ method...
void joinThreads()
Join any data-taking threads. Should be called when destructing CommandableFragmentGenerator.