1 #ifndef artdaq_Application_CommandableFragmentGenerator_hh
2 #define artdaq_Application_CommandableFragmentGenerator_hh
6 #include <netinet/in.h>
8 #include <sys/socket.h>
12 #include <condition_variable>
19 #include "fhiclcpp/fwd.h"
20 #include "fhiclcpp/ParameterSet.h"
22 #include "artdaq/DAQdata/Globals.hh"
23 #include "artdaq-core/Data/Fragment.hh"
24 #include "artdaq-core/Generators/FragmentGenerator.hh"
25 #include "artdaq-utilities/Plugins/MetricManager.hh"
26 #include "artdaq/DAQrate/RequestReceiver.hh"
151 bool getNext(FragmentPtrs& output)
override final;
196 bool sendEmptyFragment(FragmentPtrs& frags,
size_t sequenceId, std::string desc);
204 void sendEmptyFragments(FragmentPtrs& frags, std::map<Fragment::sequence_id_t, Fragment::timestamp_t>& requests);
257 return fragment_ids_;
322 std::string
ReportCmd(std::string
const& which =
"");
330 return instance_name_for_metrics_;
362 virtual bool metaCommand(std::string
const& command, std::string
const& arg);
446 instance_name_for_metrics_ = name;
470 std::unique_ptr<RequestReceiver> requestReceiver_;
473 Fragment::timestamp_t windowOffset_;
474 Fragment::timestamp_t windowWidth_;
475 Fragment::timestamp_t staleTimeout_;
476 Fragment::type_t expectedType_;
477 size_t maxFragmentCount_;
479 bool missing_request_;
480 std::chrono::steady_clock::time_point missing_request_time_;
481 std::chrono::steady_clock::time_point last_window_send_time_;
482 bool last_window_send_time_set_;
483 std::set<Fragment::sequence_id_t> windows_sent_ooo_;
484 size_t missing_request_window_timeout_us_;
485 size_t window_close_timeout_us_;
488 size_t sleep_on_no_data_us_;
489 std::atomic<bool> data_thread_running_;
490 boost::thread dataThread_;
492 std::condition_variable dataCondition_;
493 std::atomic<int> dataBufferDepthFragments_;
494 std::atomic<size_t> dataBufferDepthBytes_;
495 int maxDataBufferDepthFragments_;
496 size_t maxDataBufferDepthBytes_;
498 bool useMonitoringThread_;
499 boost::thread monitoringThread_;
500 int64_t monitoringInterval_;
501 std::chrono::steady_clock::time_point lastMonitoringCall_;
504 FragmentPtrs dataBuffer_;
505 FragmentPtrs newDataBuffer_;
506 std::mutex dataBufferMutex_;
508 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
513 int run_number_, subrun_number_;
528 std::atomic<bool> should_stop_, exception_, force_stop_;
529 std::string latest_exception_report_;
530 std::atomic<size_t> ev_counter_;
533 std::string instance_name_for_metrics_;
538 int sleep_on_stop_us_;
546 virtual bool getNext_(FragmentPtrs& output) = 0;
552 virtual bool checkHWStatus_();
564 virtual void start() = 0;
568 virtual void stopNoMutex() = 0;
574 virtual void stop() = 0;
578 virtual void pauseNoMutex();
583 virtual void pause();
589 virtual void resume();
599 virtual std::string report();
601 virtual std::string reportSpecific(std::string
const&);
int fragment_id() const
Get the current Fragment ID, if there is only one.
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.
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.
bool sendEmptyFragment(FragmentPtrs &frags, size_t sequenceId, std::string desc)
Send an EmptyFragmentType Fragment.
void getMonitoringDataLoop()
This function regularly calls checkHWStatus_(), and sets the isHardwareOK flag accordingly.
void startDataThread()
Function that launches the data thread (getDataLoop())
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.
bool dataBufferIsTooLarge()
Test the configured constraints on the data buffer.
void StopCmd(uint64_t timeout, uint64_t timestamp)
Stop the CommandableFragmentGenerator.
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.
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.
CommandableFragmentGenerator()
CommandableFragmentGenerator default constructor.
bool getNext(FragmentPtrs &output) overridefinal
getNext calls either applyRequests or getNext_ to get any data that is ready to be sent to the EventB...
bool waitForDataBufferReady()
Wait for the data buffer to drain (dataBufferIsTooLarge returns false), periodically reporting status...
size_t ev_counter_inc(size_t step=1, bool force=false)
Increment the event counter, if the current RequestMode allows it.
std::vector< Fragment::fragment_id_t > fragmentIDs() override
Get the list of Fragment IDs handled by this CommandableFragmentGenerator.
void applyRequestsIgnoredMode(artdaq::FragmentPtrs &frags)
Create fragments using data buffer for request mode Ignored. Precondition: dataBufferMutex_ and reque...
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...
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.
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
void startMonitoringThread()
Function that launches the monitoring thread (getMonitoringDataLoop())
size_t ev_counter() const
Get the current value of the event counter.
void checkDataBuffer()
Perform data buffer pruning operations. If the RequestMode is Single, removes all but the latest Frag...
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.
void getDataBufferStats()
Calculate the size of the dataBuffer and report appropriate metrics.
uint64_t timestamp() const
Timestamp of last command.
bool applyRequests(FragmentPtrs &output)
See if any requests have been received, and add the corresponding data Fragment objects to the output...
int run_number() const
Get the current Run number.
void joinThreads()
Join any data-taking threads. Should be called when destructing CommandableFragmentGenerator.