1 #define TRACE_NAME "RequestSender"
3 #include <boost/program_options.hpp>
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"
12 #include "fhiclcpp/ParameterSet.h"
13 #include "fhiclcpp/types/Atom.h"
14 #include "fhiclcpp/types/Comment.h"
15 #include "fhiclcpp/types/Name.h"
16 #include "fhiclcpp/types/TableFragment.h"
18 int main(
int argc,
char* argv[])
21 artdaq::configureMessageFacility(
"RequestSender");
25 fhicl::TableFragment<artdaq::RequestSender::Config> senderConfig;
26 fhicl::Atom<bool> use_receiver{fhicl::Name{
"use_receiver"}, fhicl::Comment{
"Whether to setup a RequestReceiver to verify that requests are being sent"},
false};
27 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};
28 fhicl::Table<artdaq::RequestReceiver::Config> receiver_config{fhicl::Name{
"receiver_config"}, fhicl::Comment{
"Configuration for RequestReceiver, if used"}};
29 fhicl::Atom<int> num_requests{fhicl::Name{
"num_requests"}, fhicl::Comment{
"Number of requests to send, 0 sends until interrupted"}, 1};
30 fhicl::Atom<double> request_rate{fhicl::Name{
"request_rate"}, fhicl::Comment{
"Rate at which to send requests, in Hz"}, 1.0};
31 fhicl::Atom<artdaq::Fragment::sequence_id_t> starting_sequence_id{fhicl::Name{
"starting_sequence_id"}, fhicl::Comment{
"Sequence ID of first request"}, 1};
32 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};
33 fhicl::Atom<artdaq::Fragment::timestamp_t> starting_timestamp{fhicl::Name{
"starting_timestamp"}, fhicl::Comment{
"Timestamp of first request"}, 1};
34 fhicl::Atom<artdaq::Fragment::timestamp_t> timestamp_scale{fhicl::Name{
"timestamp_scale"}, fhicl::Comment{
"Amount to increment timestamp for each request"}, 1};
37 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");
39 fhicl::ParameterSet tempPset;
40 if (pset.has_key(
"daq"))
42 fhicl::ParameterSet daqPset = pset.get<fhicl::ParameterSet>(
"daq");
43 for (
auto& name : daqPset.get_pset_names())
45 auto thisPset = daqPset.get<fhicl::ParameterSet>(name);
46 if (thisPset.has_key(
"send_requests"))
61 std::unique_ptr<artdaq::RequestReceiver> receiver(
nullptr);
62 std::shared_ptr<artdaq::RequestBuffer> request_buffer(
nullptr);
63 int num_requests = tempPset.get<
int>(
"num_requests", 1);
64 if (num_requests == 0) num_requests = std::numeric_limits<int>::max();
65 if (tempPset.get<
bool>(
"use_receiver",
false))
67 auto receiver_pset = tempPset.get<fhicl::ParameterSet>(
"request_receiver", fhicl::ParameterSet());
68 request_buffer = std::make_shared<artdaq::RequestBuffer>(receiver_pset.get<artdaq::Fragment::sequence_id_t>(
"request_increment", 1));
69 receiver = std::make_unique<artdaq::RequestReceiver>(receiver_pset, request_buffer);
70 receiver->startRequestReception();
73 auto seq = tempPset.get<artdaq::Fragment::sequence_id_t>(
"starting_sequence_id", 1);
74 auto seq_scale = tempPset.get<artdaq::Fragment::sequence_id_t>(
"sequence_id_scale", 1);
75 auto ts = tempPset.get<artdaq::Fragment::timestamp_t>(
"starting_timestamp", 1);
76 auto ts_scale = tempPset.get<artdaq::Fragment::timestamp_t>(
"timestamp_scale", 1);
77 auto tmo = tempPset.get<
size_t>(
"recevier_timeout_ms", 1000);
78 auto rate = tempPset.get<
double>(
"request_rate", 1.0);
79 if(rate <= 0) rate = std::numeric_limits<double>::max();
81 auto sending_start = std::chrono::steady_clock::now();
83 for (
auto ii = 0; ii < num_requests; ++ii)
85 TLOG(TLVL_INFO) <<
"Sending request " << ii <<
" of " << num_requests <<
" with sequence id " << seq;
86 sender.AddRequest(seq, ts);
91 auto start_time = std::chrono::steady_clock::now();
93 TLOG(TLVL_INFO) <<
"Starting receive loop for request " << ii;
94 while (!recvd && artdaq::TimeUtils::GetElapsedTimeMilliseconds(start_time) < tmo)
96 auto reqs = request_buffer->GetRequests();
97 if (reqs.count(seq) != 0u)
99 TLOG(TLVL_INFO) <<
"Received Request for Sequence ID " << seq <<
", timestamp " << reqs[seq];
100 request_buffer->RemoveRequest(seq);
101 sender.RemoveRequest(seq);
109 if (artdaq::TimeUtils::GetElapsedTimeMilliseconds(start_time) >= tmo)
111 TLOG(TLVL_ERROR) <<
"Timeout elapsed in requestSender";
118 auto target = sending_start + std::chrono::microseconds(static_cast<int>((ii+1) * 1000000 / rate));
119 auto now = std::chrono::steady_clock::now();
122 std::this_thread::sleep_until(target);
128 auto recvd = receiver->GetReceivedMessageCount();
129 auto sent = sender.GetSentMessageCount();
132 TLOG(TLVL_ERROR) <<
"Receiver reports reception of " << recvd <<
" messages, when sender reports sending " << sent <<
"!";
The RequestSender contains methods used to send data requests and Routing tokens. ...
Configuration for simple_metric_sender.