artdaq  v3_07_02
NetMonWrapper.cc
1 #define TRACE_NAME "NetMonWrapper"
2 
3 #include "artdaq/ArtModules/NetMonWrapper.hh"
4 #include "art/Framework/Services/Registry/ServiceHandle.h"
5 #include "artdaq/ArtModules/ArtdaqSharedMemoryService.h"
6 #include "artdaq/DAQdata/NetMonHeader.hh"
7 
8 art::NetMonWrapper::NetMonWrapper(fhicl::ParameterSet const& ps)
9 {
10  init_timeout_s_ = ps.get<double>("init_fragment_timeout_seconds", 1.0);
11  // Make sure the ArtdaqSharedMemoryService is available
12  art::ServiceHandle<ArtdaqSharedMemoryService> shm;
13 }
14 
16 {
17  TLOG(5) << "Receiving Fragment from NetMonTransportService";
18  TLOG(TLVL_TRACE) << "receiveMessage BEGIN";
19  art::ServiceHandle<ArtdaqSharedMemoryService> shm;
20 
21  // Do not process data until Init Fragment received!
22  auto start = std::chrono::steady_clock::now();
23  while (!init_received_ && artdaq::TimeUtils::GetElapsedTime(start) < init_timeout_s_)
24  {
25  usleep(init_timeout_s_ * 1000000 / 100); // Check 100 times
26  }
27  if (!init_received_)
28  {
29  TLOG(TLVL_ERROR) << "Did not receive Init Fragment after " << init_timeout_s_ << " seconds. Art will crash.";
30  return nullptr;
31  }
32 
33  artdaq::Fragments recvd_fragments;
34  while (recvd_fragments.size() == 0)
35  {
36  auto eventMap = shm->ReceiveEvent(false);
37 
38  if (eventMap.size() == 0)
39  {
40  TLOG(TLVL_DEBUG) << "Did not receive event after timeout, returning from receiveMessage ";
41  return nullptr;
42  }
43 
44  if (eventMap.count(artdaq::Fragment::type_t(artdaq::Fragment::EndOfDataFragmentType)))
45  {
46  TLOG(TLVL_DEBUG) << "Received shutdown message, returning";
47  return nullptr;
48  }
49  if (eventMap.count(artdaq::Fragment::type_t(artdaq::Fragment::DataFragmentType)))
50  {
51  std::move(eventMap[artdaq::Fragment::type_t(artdaq::Fragment::DataFragmentType)]->begin(), eventMap[artdaq::Fragment::type_t(artdaq::Fragment::DataFragmentType)]->end(), std::back_inserter(recvd_fragments));
52  }
53  std::sort(recvd_fragments.begin(), recvd_fragments.end(), artdaq::fragmentSequenceIDCompare);
54  }
55 
56  TLOG(TLVL_TRACE) << "receiveMessage: Returning top Fragment";
57  artdaq::FragmentPtr topFrag = artdaq::FragmentPtr(new artdaq::Fragment(std::move(recvd_fragments.at(0))));
58  recvd_fragments.erase(recvd_fragments.begin());
59 
60  TLOG(TLVL_TRACE) << "receiveMessage: Returning Fragment, length="
61  << topFrag->metadata<artdaq::NetMonHeader>()->data_length;
62 
63 #if DUMP_RECEIVE_MESSAGE
64  std::string fileName = "receiveMessage_" + std::to_string(my_rank) + "_" + std::to_string(getpid()) + "_" +
65  std::to_string(topFrag.sequenceID()) + ".bin";
66  std::fstream ostream(fileName.c_str(), std::ios::out | std::ios::binary);
67  ostream.write(buffer, header->data_length);
68  ostream.close();
69 #endif
70 
71  TLOG(TLVL_TRACE) << "receiveMessage END";
72 
73  TLOG(5) << "Done Receiving Fragment from NetMonTransportService";
74  return topFrag;
75 }
76 
78 {
79  TLOG(5) << "Receiving Init Fragment from NetMonTransportService";
80 
81  TLOG(TLVL_TRACE) << "receiveInitMessage BEGIN";
82  art::ServiceHandle<ArtdaqSharedMemoryService> shm;
83  std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> eventMap;
84  while (eventMap.size() == 0)
85  {
86  eventMap = shm->ReceiveEvent(true);
87 
88  if (eventMap.count(artdaq::Fragment::type_t(artdaq::Fragment::EndOfDataFragmentType)))
89  {
90  TLOG(TLVL_DEBUG) << "Received shutdown message, returning";
91  return nullptr;
92  }
93  else if (!eventMap.count(artdaq::Fragment::type_t(artdaq::Fragment::InitFragmentType)) && eventMap.size() > 0)
94  {
95  TLOG(TLVL_WARNING) << "Did NOT receive Init Fragment as first broadcast! Type="
96  << artdaq::detail::RawFragmentHeader::SystemTypeToString(eventMap.begin()->first);
97  eventMap.clear();
98  }
99  }
100 
101  // We return false, indicating we're done reading, if:
102  // 1) we did not obtain an event, because we timed out and were
103  // configured NOT to keep trying after a timeout, or
104  // 2) the event we read was the end-of-data marker: a null
105  // pointer
106 
107  TLOG(TLVL_TRACE) << "receiveInitMessage: Returning top Fragment";
108  artdaq::FragmentPtr topFrag = artdaq::FragmentPtr(new artdaq::Fragment(std::move(eventMap[artdaq::Fragment::InitFragmentType]->at(0))));
109 
110 #if DUMP_RECEIVE_MESSAGE
111  std::string fileName = "receiveInitMessage_" + std::to_string(getpid()) + ".bin";
112  std::fstream ostream(fileName.c_str(), std::ios::out | std::ios::binary);
113  ostream.write(buffer, header->data_length);
114  ostream.close();
115 #endif
116 
117  TLOG(TLVL_TRACE) << "receiveInitMessage END";
118  init_received_ = true;
119 
120  TLOG(5) << "Done Receiving Init Fragment from NetMonTransportService";
121  return topFrag;
122 }
artdaq::FragmentPtr receiveInitMessage()
Receive an init message from the NetMonTransportService.
NetMonWrapper(fhicl::ParameterSet const &ps)
NetMonWrapper Constructor.
Definition: NetMonWrapper.cc:8
Header with length information for NetMonTransport messages.
Definition: NetMonHeader.hh:13
artdaq::FragmentPtr receiveMessage()
Receive a message from the NetMonTransportService.