artdaq  v3_12_02
requestSender.cc
1 #define TRACE_NAME "RequestSender"
2 
3 #include <boost/program_options.hpp>
4 #include <memory>
5 
6 #include "artdaq-core/Utilities/configureMessageFacility.hh"
7 #include "artdaq/Application/LoadParameterSet.hh"
8 #include "artdaq/DAQrate/detail/RequestReceiver.hh"
9 #include "artdaq/DAQrate/detail/RequestSender.hh"
10 
11 #include "fhiclcpp/ParameterSet.h"
12 #include "fhiclcpp/types/Atom.h"
13 #include "fhiclcpp/types/Comment.h"
14 #include "fhiclcpp/types/Name.h"
15 #include "fhiclcpp/types/TableFragment.h"
16 
17 int main(int argc, char* argv[])
18 try
19 {
20  artdaq::configureMessageFacility("RequestSender");
21 
22  struct Config
23  {
24  fhicl::TableFragment<artdaq::RequestSender::Config> senderConfig;
25  fhicl::Atom<bool> use_receiver{fhicl::Name{"use_receiver"}, fhicl::Comment{"Whether to setup a RequestReceiver to verify that requests are being sent"}, false};
26  fhicl::Atom<size_t> receiver_timeout_ms{fhicl::Name{"recevier_timeout_ms"}, fhicl::Comment{"Amount of time to wait for the receiver to receive a request message"}, 1000};
27  fhicl::Table<artdaq::RequestReceiver::Config> receiver_config{fhicl::Name{"receiver_config"}, fhicl::Comment{"Configuration for RequestReceiver, if used"}};
28  fhicl::Atom<int> num_requests{fhicl::Name{"num_requests"}, fhicl::Comment{"Number of requests to send"}};
29  fhicl::Atom<artdaq::Fragment::sequence_id_t> starting_sequence_id{fhicl::Name{"starting_sequence_id"}, fhicl::Comment{"Sequence ID of first request"}, 1};
30  fhicl::Atom<artdaq::Fragment::sequence_id_t> sequence_id_scale{fhicl::Name{"sequence_id_scale"}, fhicl::Comment{"Amount to increment Sequence ID for each request"}, 1};
31  fhicl::Atom<artdaq::Fragment::timestamp_t> starting_timestamp{fhicl::Name{"starting_timestamp"}, fhicl::Comment{"Timestamp of first request"}, 1};
32  fhicl::Atom<artdaq::Fragment::timestamp_t> timestamp_scale{fhicl::Name{"timestamp_scale"}, fhicl::Comment{"Amount to increment timestamp for each request"}, 1};
33  };
34 
35  auto pset = LoadParameterSet<Config>(argc, argv, "sender", "This test application sends Data Request messages and optionally receives them to detect issues in the network transport");
36 
37  fhicl::ParameterSet tempPset;
38  if (pset.has_key("daq"))
39  {
40  fhicl::ParameterSet daqPset = pset.get<fhicl::ParameterSet>("daq");
41  for (auto& name : daqPset.get_pset_names())
42  {
43  auto thisPset = daqPset.get<fhicl::ParameterSet>(name);
44  if (thisPset.has_key("send_requests"))
45  {
46  tempPset = thisPset;
47  }
48  }
49  }
50  else
51  {
52  tempPset = pset;
53  }
54 
55  int rc = 0;
56 
57  artdaq::RequestSender sender(tempPset);
58 
59  std::unique_ptr<artdaq::RequestReceiver> receiver(nullptr);
60  std::shared_ptr<artdaq::RequestBuffer> request_buffer(nullptr);
61  int num_requests = tempPset.get<int>("num_requests", 1);
62  if (tempPset.get<bool>("use_receiver", false))
63  {
64  auto receiver_pset = tempPset.get<fhicl::ParameterSet>("request_receiver", fhicl::ParameterSet());
65  request_buffer = std::make_shared<artdaq::RequestBuffer>(receiver_pset.get<artdaq::Fragment::sequence_id_t>("request_increment", 1));
66  receiver = std::make_unique<artdaq::RequestReceiver>(receiver_pset, request_buffer);
67  receiver->startRequestReception();
68  }
69 
70  auto seq = tempPset.get<artdaq::Fragment::sequence_id_t>("starting_sequence_id", 1);
71  auto seq_scale = tempPset.get<artdaq::Fragment::sequence_id_t>("sequence_id_scale", 1);
72  auto ts = tempPset.get<artdaq::Fragment::timestamp_t>("starting_timestamp", 1);
73  auto ts_scale = tempPset.get<artdaq::Fragment::timestamp_t>("timestamp_scale", 1);
74  auto tmo = tempPset.get<size_t>("recevier_timeout_ms", 1000);
75 
76  for (auto ii = 0; ii < num_requests; ++ii)
77  {
78  TLOG(TLVL_INFO) << "Sending request " << ii << " of " << num_requests << " with sequence id " << seq;
79  sender.AddRequest(seq, ts);
80  sender.SendRequest();
81 
82  if (request_buffer)
83  {
84  auto start_time = std::chrono::steady_clock::now();
85  bool recvd = false;
86  TLOG(TLVL_INFO) << "Starting receive loop for request " << ii;
87  while (!recvd && artdaq::TimeUtils::GetElapsedTimeMilliseconds(start_time) < tmo)
88  {
89  auto reqs = request_buffer->GetRequests();
90  if (reqs.count(seq) != 0u)
91  {
92  TLOG(TLVL_INFO) << "Received Request for Sequence ID " << seq << ", timestamp " << reqs[seq];
93  request_buffer->RemoveRequest(seq);
94  sender.RemoveRequest(seq);
95  recvd = true;
96  }
97  else
98  {
99  usleep(10000);
100  }
101  }
102  }
103 
104  seq += seq_scale;
105  ts += ts_scale;
106  }
107 
108  return rc;
109 }
110 catch (...)
111 {
112  return -1;
113 }
The RequestSender contains methods used to send data requests and Routing tokens. ...
Configuration for simple_metric_sender.