1 #ifndef ARTDAQ_DAQRATE_REQUEST_RECEVIER_HH
2 #define ARTDAQ_DAQRATE_REQUEST_RECEVIER_HH
4 #include <boost/thread.hpp>
5 #include "artdaq-core/Data/Fragment.hh"
6 #include "fhiclcpp/ParameterSet.h"
7 #include "fhiclcpp/types/Atom.h"
8 #include "fhiclcpp/types/ConfigurationTable.h"
10 #include <condition_variable>
26 fhicl::Atom<int>
request_port{fhicl::Name{
"request_port"}, fhicl::Comment{
"Port to listen for request messages on"}, 3001};
28 fhicl::Atom<std::string>
request_addr{fhicl::Name{
"request_address"}, fhicl::Comment{
"Multicast address to listen for request messages on"},
"227.128.12.26"};
30 fhicl::Atom<std::string>
output_address{fhicl::Name{
"multicast_interface_ip"}, fhicl::Comment{
"Use this hostname for multicast (to assign to the proper NIC)"},
"0.0.0.0"};
32 fhicl::Atom<size_t>
end_of_run_timeout_ms{fhicl::Name{
"end_of_run_quiet_timeout_ms"}, fhicl::Comment{
"Amount of time (in ms) to wait for no new requests when a Stop transition is pending"}, 1000};
34 fhicl::Atom<artdaq::Fragment::sequence_id_t>
request_increment{fhicl::Name{
"request_increment"}, fhicl::Comment{
"Expected increment of sequence ID between each request"}, 1};
76 std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t>
GetRequests()
const
78 std::unique_lock<std::mutex> lk(request_mutex_);
79 std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
80 for (
auto& in : requests_)
82 out[in.first] = in.second;
93 std::pair<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t>
GetNextRequest();
112 std::unique_lock<std::mutex> lk(request_mutex_);
122 std::unique_lock<std::mutex> lk(request_mutex_);
123 std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
124 for (
auto& in : requests_)
126 out[in.first] = in.second;
128 if (requests_.size()) { highest_seen_request_ = requests_.rbegin()->first; }
129 out_of_order_requests_.clear();
131 request_timing_.clear();
141 std::unique_lock<std::mutex> tlk(request_mutex_);
142 return requests_.size();
152 std::unique_lock<std::mutex> lk(request_mutex_);
154 if (requests_.size() > 0)
return true;
156 return request_cv_.wait_for(lk, std::chrono::milliseconds(timeout_ms), [
this]() {
return requests_.size() > 0; });
164 std::chrono::steady_clock::time_point
GetRequestTime(artdaq::Fragment::sequence_id_t reqID)
166 std::unique_lock<std::mutex> lk(request_mutex_);
167 return request_timing_.count(reqID) ? request_timing_[reqID] : std::chrono::steady_clock::now();
180 std::string request_addr_;
181 std::string multicast_in_addr_;
183 uint32_t run_number_;
187 std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> requests_;
188 std::map<artdaq::Fragment::sequence_id_t, std::chrono::steady_clock::time_point> request_timing_;
189 std::atomic<bool> request_stop_requested_;
190 std::chrono::steady_clock::time_point request_stop_timeout_;
191 std::atomic<bool> request_received_;
192 size_t end_of_run_timeout_ms_;
193 std::atomic<bool> should_stop_;
194 mutable std::mutex request_mutex_;
195 mutable std::mutex state_mutex_;
196 std::condition_variable request_cv_;
197 boost::thread requestThread_;
199 std::atomic<artdaq::Fragment::sequence_id_t> highest_seen_request_;
200 std::atomic<artdaq::Fragment::sequence_id_t> last_next_request_;
201 std::set<artdaq::Fragment::sequence_id_t> out_of_order_requests_;
202 artdaq::Fragment::sequence_id_t request_increment_;
206 #endif //ARTDAQ_DAQRATE_REQUEST_RECEVIER_HH
void startRequestReception()
Enables (starts) the reception of data requests.
fhicl::Atom< size_t > end_of_run_timeout_ms
"end_of_run_quiet_timeout_ms" (Default: 1000) : Time, in milliseconds, that the entire system must be...
std::chrono::steady_clock::time_point GetRequestTime(artdaq::Fragment::sequence_id_t reqID)
Get the time a given request was received
size_t size()
Get the number of requests currently stored in the RequestReceiver
fhicl::Atom< std::string > request_addr
"request_address" (Default: "227.128.12.26") : Address which CommandableFragmentGenerator will listen...
fhicl::Atom< std::string > output_address
"multicast_interface_ip" (Default: "0.0.0.0") : Use this hostname for multicast(to assign to the prop...
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
RequestReceiver()
RequestReceiver Default Constructor.
bool isRunning()
Determine if the RequestReceiver is receiving requests
void setupRequestListener()
Opens the socket used to listen for data requests.
void receiveRequestsLoop()
This function receives data request packets, adding new requests to the request list.
Receive data requests and make them available to CommandableFragmentGenerator or other interested par...
std::pair< artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t > GetNextRequest()
Get the "next" request, i.e. the first unsatisfied request that has not already been returned by GetN...
std::map< artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t > GetAndClearRequests()
Get the current requests, then clear the map
void ClearRequests()
Clear all requests from the map
void SetRunNumber(uint32_t run)
Sets the current run number
bool WaitForRequests(int timeout_ms)
Wait for a new request message, up to the timeout given
fhicl::Atom< int > request_port
"request_port" (Default: 3001) : Port on which data requests will be received
void stopRequestReception(bool force=false)
Disables (stops) the reception of data requests.
void RemoveRequest(artdaq::Fragment::sequence_id_t reqID)
Remove the request with the given sequence ID from the request map
fhicl::Atom< artdaq::Fragment::sequence_id_t > request_increment
"request_increment" (Default: 1) : Expected increment of sequence ID between each request ...
std::map< artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t > GetRequests() const
Get the current requests
Configuration of the RequestReceiver. May be used for parameter validation