artdaq  v3_12_02
transfer_plugin_sender.cc
1 #include "artdaq-core/Data/Fragment.hh"
2 #include "artdaq-core/Utilities/ExceptionHandler.hh"
3 #include "artdaq/TransferPlugins/TransferInterface.hh"
4 
5 #include "cetlib/BasicPluginFactory.h"
6 #include "cetlib/filepath_maker.h"
7 #include "fhiclcpp/ParameterSet.h"
8 
9 #include <boost/asio.hpp>
10 #include <boost/lexical_cast.hpp>
11 
12 #include <algorithm>
13 #include <cstdlib>
14 #include <iostream>
15 #include <limits>
16 #include <memory>
17 #include <numeric>
18 #include <sstream>
19 #include <string>
20 
21 // DUPLICATED CODE: also found in transfer_plugin_receiver.cpp. Not as
22 // egregious as normal in that this function is unlikely to be
23 // changed, and this is a standalone app (not part of artdaq)
24 
25 fhicl::ParameterSet ReadParameterSet(const std::string& fhicl_filename)
26 {
27  if (std::getenv("FHICL_FILE_PATH") == nullptr)
28  {
29  std::cerr
30  << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
31  setenv("FHICL_FILE_PATH", ".", 0);
32  }
33 
34  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
35  auto pset = fhicl::ParameterSet::make(fhicl_filename, lookup_policy);
36 
37  return pset;
38 }
39 
40 int main(int argc, char* argv[])
41 try
42 {
43  if (argc != 4)
44  {
45  std::cerr << "Usage: <fhicl document> <number of sends (should be greater than 1) > <fragment payload size>" << std::endl;
46  return 1;
47  }
48 
49  auto fhicl_filename = boost::lexical_cast<std::string>(argv[1]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
50  auto num_sends = boost::lexical_cast<size_t>(argv[2]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
51  auto fragment_size = boost::lexical_cast<size_t>(argv[3]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
52 
53  if (num_sends <= 1)
54  {
55  std::cerr << "Logic in the program requires requested # of sends to be greater than 1" << std::endl;
56  return 1;
57  }
58 
59  std::unique_ptr<artdaq::TransferInterface> transfer;
60 
61  auto pset = ReadParameterSet(fhicl_filename);
62 
63  try
64  {
65  static cet::BasicPluginFactory bpf("transfer", "make");
66 
67  transfer =
68  bpf.makePlugin<std::unique_ptr<artdaq::TransferInterface>,
69  const fhicl::ParameterSet&,
71  pset.get<std::string>("transfer_plugin_type"),
72  pset,
74  }
75  catch (...)
76  {
77  artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
78  "Error creating transfer plugin");
79  return 1;
80  }
81 
82  std::unique_ptr<artdaq::Fragment> frag = artdaq::Fragment::FragmentBytes(fragment_size);
83 
84  struct ArbitraryMetadata
85  {
86  const uint64_t val1 = 0;
87  const uint32_t val2 = 0;
88  };
89 
90  ArbitraryMetadata arbitraryMetadata;
91 
92  frag->setMetadata(arbitraryMetadata);
93 
94  // Fill the fragment with monotonically increasing 64-bit integers
95  // to be checked on the other end
96 
97  std::iota(reinterpret_cast<uint64_t*>(frag->dataBeginBytes()), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
98  reinterpret_cast<uint64_t*>(frag->dataEndBytes()), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
99  0);
100 
101  auto timeout = pset.get<size_t>("send_timeout_usecs", std::numeric_limits<size_t>::max());
102 
103  for (size_t i_i = 0; i_i < num_sends; ++i_i)
104  {
105  frag->setSequenceID(i_i + 1);
106  frag->setFragmentID(0);
107  frag->setUserType(artdaq::Fragment::FirstUserFragmentType);
108 
109  transfer->transfer_fragment_min_blocking_mode(*frag, timeout);
110  }
111 
112  std::cout << "# of sent fragments attempted == " << num_sends << std::endl;
113 
114  return 0;
115 }
116 catch (...)
117 {
118  return -1;
119 }
This TransferInterface is a Sender.
Role
Used to determine if a TransferInterface is a Sender or Receiver.