artdaq  v3_12_02
DataSenderManager.hh
1 #ifndef ARTDAQ_DAQRATE_DATASENDERMANAGER_HH
2 #define ARTDAQ_DAQRATE_DATASENDERMANAGER_HH
3 
4 #include "fhiclcpp/types/Sequence.h" // Must pre-empt fhiclcpp/types/Atom.h
5 
6 #include "TRACE/tracemf.h" // Pre-empt TRACE/trace.h from Fragment.hh.
7 #include "artdaq-core/Data/Fragment.hh"
8 
9 #include "artdaq/DAQdata/HostMap.hh"
10 #include "artdaq/DAQrate/detail/FragCounter.hh"
11 #include "artdaq/DAQrate/detail/TableReceiver.hh"
12 #include "artdaq/TransferPlugins/TransferInterface.hh"
13 
14 #include "fhiclcpp/types/Atom.h"
15 #include "fhiclcpp/types/Comment.h"
16 #include "fhiclcpp/types/ConfigurationTable.h"
17 #include "fhiclcpp/types/Name.h"
18 #include "fhiclcpp/types/OptionalTable.h"
19 #include "fhiclcpp/types/TableFragment.h"
20 
21 #include <netinet/in.h>
22 #include <atomic>
23 #include <map>
24 #include <memory>
25 #include <set>
26 
27 namespace artdaq {
28 class DataSenderManager;
29 }
30 
36 {
37 public:
42  {
44  fhicl::OptionalTable<artdaq::TransferInterface::Config> dest{fhicl::Name{"d1"}, fhicl::Comment{"Configuration for transfer to destination"}};
45  };
46 
50  struct Config
51  {
53  fhicl::Atom<bool> broadcast_sends{fhicl::Name{"broadcast_sends"}, fhicl::Comment{"Send all Fragments to all destinations"}, false};
55  fhicl::Atom<bool> nonblocking_sends{fhicl::Name{"nonblocking_sends"}, fhicl::Comment{"Whether sends should block. Used for DL->DISP connection."}, false};
57  fhicl::Atom<size_t> send_timeout_us{fhicl::Name{"send_timeout_usec"}, fhicl::Comment{"Timeout for sends in non-reliable modes (broadcast and nonblocking)"}, 5000000};
59  fhicl::Atom<size_t> send_retry_count{fhicl::Name{"send_retry_count"}, fhicl::Comment{"Number of times to retry a send in non-reliable mode"}, 2};
60  fhicl::OptionalTable<artdaq::TableReceiver::Config> routing_table_config{fhicl::Name{"routing_table_config"}};
61  fhicl::OptionalTable<DestinationsConfig> destinations{fhicl::Name{"destinations"}};
65  fhicl::TableFragment<artdaq::HostMap::Config> host_map;
67  fhicl::Sequence<size_t> enabled_destinations{fhicl::Name{"enabled_destinations"}, fhicl::Comment{"List of destiantion ranks to activate (must be defined in destinations block)"}, std::vector<size_t>()};
68  };
70  using Parameters = fhicl::WrappedTable<Config>;
71 
76  explicit DataSenderManager(const fhicl::ParameterSet& ps);
77 
81  virtual ~DataSenderManager();
82 
88  std::pair<int, TransferInterface::CopyStatus> sendFragment(Fragment&& frag);
89 
94  size_t count() const;
95 
101  size_t slotCount(size_t rank) const;
102 
107  size_t destinationCount() const { return destinations_.size(); }
108 
113  std::set<int> enabled_destinations() const { return enabled_destinations_; }
114 
119  size_t GetRoutingTableEntryCount() const;
120 
125  size_t GetRemainingRoutingTableEntries() const;
126 
130  void StopSender() { should_stop_ = true; }
131 
136  void RemoveRoutingTableEntry(Fragment::sequence_id_t seq);
142  size_t GetSentSequenceIDCount(Fragment::sequence_id_t seq);
143 
144 private:
145  DataSenderManager(DataSenderManager const&) = delete;
147  DataSenderManager& operator=(DataSenderManager const&) = delete;
148  DataSenderManager& operator=(DataSenderManager&&) = delete;
149 
150  // Calculate where the fragment with this sequenceID should go.
151  int calcDest_(Fragment::sequence_id_t) const;
152 
153 private:
154  std::map<int, std::unique_ptr<artdaq::TransferInterface>> destinations_;
155  std::set<int> enabled_destinations_;
156 
157  detail::FragCounter sent_frag_count_;
158 
159  bool broadcast_sends_;
160  bool non_blocking_mode_;
161  size_t send_timeout_us_;
162  size_t send_retry_count_;
163 
164  std::unique_ptr<TableReceiver> table_receiver_;
165  std::atomic<bool> should_stop_;
166  std::map<Fragment::sequence_id_t, size_t> sent_sequence_id_count_;
167 
168  mutable std::mutex sent_sequence_id_mutex_;
169 
170  mutable std::atomic<uint64_t> highest_sequence_id_routed_;
171 };
172 
173 inline size_t
175  count() const
176 {
177  return sent_frag_count_.count();
178 }
179 
180 inline size_t
182  slotCount(size_t rank) const
183 {
184  return sent_frag_count_.slotCount(rank);
185 }
186 #endif // ARTDAQ_DAQRATE_DATASENDERMANAGER_HH
fhicl::TableFragment< artdaq::HostMap::Config > host_map
Optional host_map configuration (Can also be specified in each DestinationsConfig entry...
void RemoveRoutingTableEntry(Fragment::sequence_id_t seq)
Remove the given sequence ID from the routing table and sent_count lists.
size_t destinationCount() const
Get the number of configured destinations.
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
Sends Fragment objects using TransferInterface plugins. Uses Routing Tables if confgiured, otherwise will Round-Robin Fragments to the destinations.
virtual ~DataSenderManager()
DataSenderManager Destructor.
fhicl::OptionalTable< artdaq::TableReceiver::Config > routing_table_config
size_t slotCount(size_t rank) const
Get the count of Fragment objects sent by this DataSenderManager to a given destination.
fhicl::OptionalTable< artdaq::TransferInterface::Config > dest
Example Configuration for transfer to destination. See artdaq::TransferInterface::Config.
Keep track of the count of Fragments received from a set of sources.
Definition: FragCounter.hh:18
size_t GetSentSequenceIDCount(Fragment::sequence_id_t seq)
Get the number of Fragments sent with a given Sequence ID.
fhicl::Atom< size_t > send_timeout_us
&quot;send_timeout_usec&quot; (Default: 5000000 (5 seconds): Timeout for sends in non-reliable modes (broadcast...
fhicl::OptionalTable< DestinationsConfig > destinations
std::pair< int, TransferInterface::CopyStatus > sendFragment(Fragment &&frag)
Send the given Fragment. Return the rank of the destination to which the Fragment was sent...
size_t GetRemainingRoutingTableEntries() const
Gets the number of sends remaining in the routing table, in case other parts of the system want to us...
DataSenderManager(const fhicl::ParameterSet &ps)
DataSenderManager Constructor.
fhicl::Atom< size_t > send_retry_count
&quot;send_retry_count&quot; (Default: 2): Number of times to retry a send in non-reliable mode ...
fhicl::Atom< bool > broadcast_sends
&quot;broadcast_sends&quot; (Default: false): Send all Fragments to all destinations
size_t GetRoutingTableEntryCount() const
Gets the current size of the Routing Table, in case other parts of the system want to use this inform...
size_t count() const
Return the count of Fragment objects sent by this DataSenderManagerq.
Configuration for transfers to destinations
size_t slotCount(size_t slot) const
Get the current count for the requested slot.
Definition: FragCounter.hh:133
Configuration of DataSenderManager. May be used for parameter validation
fhicl::Sequence< size_t > enabled_destinations
enabled_destinations" (OPTIONAL): If specified, only the destination ranks listed will be enabled...
void StopSender()
Stop the DataSenderManager, aborting any sends in progress.
std::set< int > enabled_destinations() const
Get the list of enabled destinations.
size_t count() const
Get the total number of Fragments received.
Definition: FragCounter.hh:120
fhicl::Atom< bool > nonblocking_sends
&quot;nonblocking_sends&quot; (Default: false): If true, will use non-reliable mode of TransferInterface plugin...