1 #include "artdaq/DAQdata/Globals.hh"
2 #define TRACE_NAME (app_name + "_RequestBuffer").c_str() // include these 2 first -
4 #include "artdaq/DAQrate/RequestBuffer.hh"
10 , highest_seen_request_(0)
11 , last_next_request_(0)
12 , out_of_order_requests_()
13 , request_increment_(request_increment)
14 , receiver_running_(false)
22 std::lock_guard<std::mutex> tlk(request_mutex_);
23 if (requests_.count(seq) && requests_[seq] != ts)
25 TLOG(TLVL_ERROR) <<
"Received conflicting request for SeqID "
27 <<
" Old ts=" << requests_[seq]
28 <<
", new ts=" << ts <<
". Keeping OLD!";
30 else if (!requests_.count(seq))
32 int delta = seq - highest_seen_request_;
33 TLOG(TLVL_DEBUG + 36) <<
"Received request for sequence ID " << seq
34 <<
" and timestamp " << ts <<
" (delta: " << delta <<
")";
35 if (delta <= 0 || out_of_order_requests_.count(seq))
37 TLOG(TLVL_DEBUG + 36) <<
"Already serviced this request ( sequence ID " << seq <<
")! Ignoring...";
42 request_timing_[seq] = std::chrono::steady_clock::now();
45 request_cv_.notify_all();
50 std::lock_guard<std::mutex> lk(request_mutex_);
52 request_timing_.clear();
53 highest_seen_request_ = 0;
54 last_next_request_ = 0;
55 out_of_order_requests_.clear();
65 std::lock_guard<std::mutex> lk(request_mutex_);
66 std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
67 for (
auto& in : requests_)
69 out[in.first] = in.second;
76 std::lock_guard<std::mutex> lk(request_mutex_);
78 auto it = requests_.begin();
79 while (it != requests_.end() && it->first <= last_next_request_) { ++it; }
81 if (it == requests_.end())
83 return std::make_pair<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t>(0, 0);
86 last_next_request_ = it->first;
92 TLOG(TLVL_DEBUG + 35) <<
"RemoveRequest: Removing request for id " << reqID;
93 std::lock_guard<std::mutex> lk(request_mutex_);
94 requests_.erase(reqID);
96 if (reqID > highest_seen_request_)
98 TLOG(TLVL_DEBUG + 35) <<
"RemoveRequest: out_of_order_requests_.size() == " << out_of_order_requests_.size() <<
", reqID=" << reqID <<
", expected=" << highest_seen_request_ + request_increment_;
99 if (out_of_order_requests_.size() || reqID != highest_seen_request_ + request_increment_)
101 out_of_order_requests_.insert(reqID);
103 auto it = out_of_order_requests_.begin();
104 while (it != out_of_order_requests_.end())
106 if (*it == highest_seen_request_ + request_increment_)
108 highest_seen_request_ = *it;
109 it = out_of_order_requests_.erase(it);
119 highest_seen_request_ = reqID;
121 TLOG(TLVL_DEBUG + 35) <<
"RemoveRequest: reqID=" << reqID <<
" Setting highest_seen_request_ to " << highest_seen_request_;
123 if (metricMan && request_timing_.count(reqID))
125 metricMan->sendMetric(
"Request Response Time", TimeUtils::GetElapsedTime(request_timing_[reqID]),
"seconds", 2, MetricMode::Average);
127 request_timing_.erase(reqID);
136 std::lock_guard<std::mutex> lk(request_mutex_);
147 std::lock_guard<std::mutex> lk(request_mutex_);
148 std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
149 for (
auto& in : requests_)
151 out[in.first] = in.second;
153 if (requests_.size()) { highest_seen_request_ = requests_.rbegin()->first; }
154 out_of_order_requests_.clear();
156 request_timing_.clear();
167 std::lock_guard<std::mutex> tlk(request_mutex_);
168 return requests_.size();
179 std::unique_lock<std::mutex> lk(request_mutex_);
181 if (requests_.size() > 0)
return true;
183 return request_cv_.wait_for(lk, std::chrono::milliseconds(timeout_ms), [
this]() {
return requests_.size() > 0; });
194 std::lock_guard<std::mutex> lk(request_mutex_);
195 return request_timing_.count(reqID) ? request_timing_[reqID] : std::chrono::steady_clock::now();
void push(artdaq::Fragment::sequence_id_t seq, artdaq::Fragment::timestamp_t ts)
Add a Request to the buffer.
virtual ~RequestBuffer()
RequestBuffer Destructor.
void ClearRequests()
Clear all requests from the map
std::map< artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t > GetAndClearRequests()
Get the current requests, then clear the map
void reset()
Reset RequestBuffer, discarding all requests and tracking information.
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 > GetRequests() const
Get the current requests
std::chrono::steady_clock::time_point GetRequestTime(artdaq::Fragment::sequence_id_t reqID)
Get the time a given request was received
bool WaitForRequests(int timeout_ms)
Wait for a new request message, up to the timeout given
RequestBuffer(Fragment::sequence_id_t request_increment=1)
RequestBuffer Constructor.
void RemoveRequest(artdaq::Fragment::sequence_id_t reqID)
Remove the request with the given sequence ID from the request map
size_t size()
Get the number of requests currently stored in the RequestReceiver