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