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_;
437 instance_name_for_metrics_ = name;
461 struct sockaddr_in si_data_;
462 std::unique_ptr<RequestReceiver> requestReceiver_;
465 Fragment::timestamp_t windowOffset_;
466 Fragment::timestamp_t windowWidth_;
467 Fragment::timestamp_t staleTimeout_;
468 Fragment::type_t expectedType_;
469 size_t maxFragmentCount_;
471 bool missing_request_;
472 std::chrono::steady_clock::time_point missing_request_time_;
473 std::chrono::steady_clock::time_point last_window_send_time_;
474 bool last_window_send_time_set_;
475 std::set<Fragment::sequence_id_t> windows_sent_ooo_;
476 size_t missing_request_window_timeout_us_;
477 size_t window_close_timeout_us_;
480 size_t sleep_on_no_data_us_;
481 std::atomic<bool> data_thread_running_;
482 boost::thread dataThread_;
484 std::condition_variable dataCondition_;
485 std::atomic<int> dataBufferDepthFragments_;
486 std::atomic<size_t> dataBufferDepthBytes_;
487 int maxDataBufferDepthFragments_;
488 size_t maxDataBufferDepthBytes_;
490 bool useMonitoringThread_;
491 boost::thread monitoringThread_;
492 int64_t monitoringInterval_;
493 std::chrono::steady_clock::time_point lastMonitoringCall_;
496 FragmentPtrs dataBuffer_;
497 FragmentPtrs newDataBuffer_;
498 std::mutex dataBufferMutex_;
500 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
505 int run_number_, subrun_number_;
520 std::atomic<bool> should_stop_, exception_, force_stop_;
521 std::string latest_exception_report_;
522 std::atomic<size_t> ev_counter_;
525 std::string instance_name_for_metrics_;
530 int sleep_on_stop_us_;
538 virtual bool getNext_(FragmentPtrs& output) = 0;
544 virtual bool checkHWStatus_();
556 virtual void start() = 0;
560 virtual void stopNoMutex() = 0;
566 virtual void stop() = 0;
570 virtual void pauseNoMutex();
575 virtual void pause();
581 virtual void resume();
591 virtual std::string report();
593 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.
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.