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