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"
21 #include "artdaq-core/Data/Fragment.hh"
22 #include "artdaq-core/Generators/FragmentGenerator.hh"
23 #include "artdaq-utilities/Plugins/MetricManager.hh"
24 #include "artdaq/DAQrate/detail/RequestMessage.hh"
25 #include "artdaq/DAQdata/Globals.hh"
150 bool getNext(FragmentPtrs& output)
override final;
200 bool sendEmptyFragment(FragmentPtrs& frags,
size_t sequenceId, std::string desc);
270 return fragment_ids_;
335 std::string
ReportCmd(std::string
const& which =
"");
343 return instance_name_for_metrics_;
450 instance_name_for_metrics_ = name;
473 std::string request_addr_;
476 struct sockaddr_in si_data_;
478 std::map<Fragment::sequence_id_t, Fragment::timestamp_t> requests_;
479 std::atomic<bool> request_stop_requested_;
480 std::chrono::steady_clock::time_point request_stop_timeout_;
481 std::atomic<bool> request_received_;
482 size_t end_of_run_timeout_ms_;
483 std::mutex request_mutex_;
484 boost::thread requestThread_;
487 Fragment::timestamp_t windowOffset_;
488 Fragment::timestamp_t windowWidth_;
489 Fragment::timestamp_t staleTimeout_;
490 Fragment::type_t expectedType_;
491 size_t maxFragmentCount_;
493 bool missing_request_;
494 std::chrono::steady_clock::time_point missing_request_time_;
495 std::chrono::steady_clock::time_point last_window_send_time_;
497 bool last_window_send_time_set_;
498 size_t missing_request_window_timeout_us_;
499 size_t window_close_timeout_us_;
502 size_t sleep_on_no_data_us_;
503 std::atomic<bool> data_thread_running_;
504 boost::thread dataThread_;
506 std::condition_variable requestCondition_;
507 std::condition_variable dataCondition_;
508 std::atomic<int> dataBufferDepthFragments_;
509 std::atomic<size_t> dataBufferDepthBytes_;
510 int maxDataBufferDepthFragments_;
511 size_t maxDataBufferDepthBytes_;
513 bool useMonitoringThread_;
514 boost::thread monitoringThread_;
515 int64_t monitoringInterval_;
516 std::chrono::steady_clock::time_point lastMonitoringCall_;
519 FragmentPtrs dataBuffer_;
520 FragmentPtrs newDataBuffer_;
521 std::mutex dataBufferMutex_;
523 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
528 int run_number_, subrun_number_;
543 std::atomic<bool> should_stop_, exception_, force_stop_;
544 std::string latest_exception_report_;
545 std::atomic<size_t> ev_counter_;
548 std::string instance_name_for_metrics_;
553 int sleep_on_stop_us_;
561 virtual bool getNext_(FragmentPtrs& output) = 0;
567 virtual bool checkHWStatus_();
579 virtual void start() = 0;
583 virtual void stopNoMutex() = 0;
589 virtual void stop() = 0;
593 virtual void pauseNoMutex();
598 virtual void pause();
604 virtual void resume();
614 virtual std::string report();
616 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.
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.
bool should_stop() const
Get the current value of the should_stop flag.
void startRequestReceiverThread()
Function that launches the data request receiver thread (receiveRequestsLoop())
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 sendEmptyFragments(FragmentPtrs &frags)
This function is for Buffered and Single request modes, as they can only respond to one data request ...
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...
void receiveRequestsLoop()
This function receives data request packets, adding new requests to the request list.
void setupRequestListener()
Opens the socket used to listen for data requests.
int run_number() const
Get the current Run number.
void joinThreads()
Join any data-taking threads. Should be called when destructing CommandableFragmentGenerator.