LCOV - code coverage report
Current view: top level - artdaq/DAQrate - RequestBuffer.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 81.1 % 95 77
Test Date: 2026-10-29 00:35:58 Functions: 73.7 % 19 14

            Line data    Source code
       1              : #include "artdaq/DAQdata/Globals.hh"
       2              : #define TRACE_NAME (app_name + "_RequestBuffer").c_str()  // include these 2 first -
       3              : 
       4              : #include "artdaq/DAQrate/RequestBuffer.hh"
       5              : 
       6           27 : artdaq::RequestBuffer::RequestBuffer()
       7              : 
       8           27 :     : requests_()
       9           27 :     , request_timing_()
      10           27 :     , next_requests_()
      11           54 :     , receiver_running_(false)
      12              : {
      13           27 : }
      14              : 
      15           27 : artdaq::RequestBuffer::~RequestBuffer() {}
      16              : 
      17       400072 : void artdaq::RequestBuffer::push(artdaq::Fragment::sequence_id_t seq, artdaq::Fragment::timestamp_t ts)
      18              : {
      19       400072 :         std::lock_guard<std::mutex> tlk(request_mutex_);
      20       400072 :         if (requests_.count(seq) && requests_[seq] != ts)
      21              :         {
      22            0 :                 TLOG(TLVL_ERROR) << "Received conflicting request for SeqID "
      23            0 :                                  << seq << "!"
      24            0 :                                  << " Old ts=" << requests_[seq]
      25            0 :                                  << ", new ts=" << ts << ". Keeping OLD!";
      26              :         }
      27       400072 :         else if (!requests_.count(seq))
      28              :         {
      29       800144 :                 TLOG(TLVL_DEBUG + 36) << "Received request for sequence ID " << seq
      30       400072 :                                       << " and timestamp " << ts;
      31       400072 :                 if (recently_completed_requests_.count(seq))
      32              :                 {
      33            0 :                         TLOG(TLVL_DEBUG + 36) << "Already serviced this request ( sequence ID " << seq << ")! Ignoring...";
      34              :                 }
      35              :                 else
      36              :                 {
      37       400072 :                         requests_[seq] = ts;
      38       400072 :                         request_timing_[seq] = std::chrono::steady_clock::now();
      39              :                 }
      40              :         }
      41       400072 :         request_cv_.notify_all();
      42       400072 : }
      43              : 
      44            1 : void artdaq::RequestBuffer::reset()
      45              : {
      46            1 :         std::lock_guard<std::mutex> lk(request_mutex_);
      47            1 :         requests_.clear();
      48            1 :         request_timing_.clear();
      49            1 :         next_requests_.clear();
      50            1 :         recently_completed_requests_.clear();
      51            1 : }
      52              : 
      53              : /// <summary>
      54              : /// Get the current requests
      55              : /// </summary>
      56              : /// <returns>Map relating sequence IDs to timestamps</returns>
      57           49 : std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> artdaq::RequestBuffer::GetRequests() const
      58              : {
      59           49 :         std::lock_guard<std::mutex> lk(request_mutex_);
      60           49 :         std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
      61       264995 :         for (auto& in : requests_)
      62              :         {
      63       264946 :                 out[in.first] = in.second;
      64              :         }
      65           98 :         return out;
      66           49 : }
      67              : 
      68           87 : std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> artdaq::RequestBuffer::GetRequests(std::chrono::steady_clock::time_point older_than) const
      69              : {
      70           87 :         std::lock_guard<std::mutex> lk(request_mutex_);
      71           87 :         std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
      72        91665 :         for (auto& in : requests_)
      73              :         {
      74        91578 :                 if (request_timing_.count(in.first) && request_timing_.at(in.first) < older_than)
      75              :                 {
      76        35099 :                         out[in.first] = in.second;
      77              :                 }
      78              :         }
      79          174 :         return out;
      80           87 : }
      81              : 
      82            0 : std::pair<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> artdaq::RequestBuffer::GetNextRequest()
      83              : {
      84            0 :         std::lock_guard<std::mutex> lk(request_mutex_);
      85              : 
      86            0 :         auto it = requests_.begin();
      87            0 :         while (it != requests_.end() && next_requests_.count(it->first)) { ++it; }
      88              : 
      89            0 :         if (it == requests_.end())
      90              :         {
      91            0 :                 return std::make_pair<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t>(0, 0);
      92              :         }
      93              : 
      94            0 :         next_requests_.insert(it->first);
      95            0 :         return *it;
      96            0 : }
      97              : 
      98       300031 : void artdaq::RequestBuffer::RemoveRequest(artdaq::Fragment::sequence_id_t reqID)
      99              : {
     100       600062 :         TLOG(TLVL_DEBUG + 35) << "RemoveRequest: Removing request for id " << reqID;
     101       300031 :         std::lock_guard<std::mutex> lk(request_mutex_);
     102       300031 :         requests_.erase(reqID);
     103       300031 :         next_requests_.erase(reqID);
     104       300031 :         recently_completed_requests_.insert(reqID);
     105              : 
     106       597031 :         while (recently_completed_requests_.size() > recently_completed_request_history_size_)
     107              :         {
     108       297000 :                 recently_completed_requests_.erase(recently_completed_requests_.begin());
     109              :         }
     110              : 
     111       300031 :         if (metricMan && request_timing_.count(reqID))
     112              :         {
     113      2100217 :                 metricMan->sendMetric("Request Response Time", TimeUtils::GetElapsedTime(request_timing_[reqID]), "seconds", 2, MetricMode::Average);
     114              :         }
     115       300031 :         request_timing_.erase(reqID);
     116       300031 : }
     117              : 
     118              : /// <summary>
     119              : /// Clear all requests from the map
     120              : /// </summary>
     121              : 
     122            0 : void artdaq::RequestBuffer::ClearRequests()
     123              : {
     124            0 :         GetAndClearRequests();
     125            0 : }
     126              : 
     127              : /// <summary>
     128              : /// Get the current requests, then clear the map
     129              : /// </summary>
     130              : /// <returns>Map relating sequence IDs to timestamps</returns>
     131              : 
     132           33 : std::map<artdaq::Fragment::sequence_id_t, artdaq::Fragment::timestamp_t> artdaq::RequestBuffer::GetAndClearRequests()
     133              : {
     134           33 :         std::lock_guard<std::mutex> lk(request_mutex_);
     135           33 :         std::map<artdaq::Fragment::sequence_id_t, Fragment::timestamp_t> out;
     136           70 :         for (auto& in : requests_)
     137              :         {
     138           37 :                 out[in.first] = in.second;
     139           37 :                 recently_completed_requests_.insert(in.first);
     140              :         }
     141           33 :         while (recently_completed_requests_.size() > recently_completed_request_history_size_)
     142              :         {
     143            0 :                 recently_completed_requests_.erase(recently_completed_requests_.begin());
     144              :         }
     145              : 
     146           33 :         next_requests_.clear();
     147           33 :         requests_.clear();
     148           33 :         request_timing_.clear();
     149           66 :         return out;
     150           33 : }
     151              : 
     152              : /// <summary>
     153              : /// Get the number of requests currently stored in the RequestReceiver
     154              : /// </summary>
     155              : /// <returns>The number of requests stored in the RequestReceiver</returns>
     156              : 
     157          182 : size_t artdaq::RequestBuffer::size()
     158              : {
     159          182 :         std::lock_guard<std::mutex> tlk(request_mutex_);
     160          364 :         return requests_.size();
     161          182 : }
     162              : 
     163              : /// <summary>
     164              : /// Wait for a new request message, up to the timeout given
     165              : /// </summary>
     166              : /// <param name="timeout_ms">Milliseconds to wait for a new request to arrive</param>
     167              : /// <returns>True if any requests are present in the request map</returns>
     168              : 
     169          100 : bool artdaq::RequestBuffer::WaitForRequests(int timeout_ms)
     170              : {
     171          100 :         std::unique_lock<std::mutex> lk(request_mutex_);  // Lock needed by wait_for
     172              :         // See if we have to wait at all
     173          100 :         if (requests_.size() > 0) return true;
     174              :         // If we do have to wait, check requests_.size to make sure we're not being notified spuriously
     175          300 :         return request_cv_.wait_for(lk, std::chrono::milliseconds(timeout_ms), [this]() { return requests_.size() > 0; });
     176          100 : }
     177              : 
     178              : /// <summary>
     179              : /// Get the time a given request was received
     180              : /// </summary>
     181              : /// <param name="reqID">Request ID of the request</param>
     182              : /// <returns>steady_clock::time_point corresponding to when the request was received</returns>
     183              : 
     184           30 : std::chrono::steady_clock::time_point artdaq::RequestBuffer::GetRequestTime(artdaq::Fragment::sequence_id_t reqID)
     185              : {
     186           30 :         std::lock_guard<std::mutex> lk(request_mutex_);
     187           60 :         return request_timing_.count(reqID) ? request_timing_[reqID] : std::chrono::steady_clock::now();
     188           30 : }
        

Generated by: LCOV version 2.0-1