artdaq  v3_08_00
RootNetOutput_module.cc
1 
2 #include "art/Framework/Services/Registry/ServiceHandle.h"
3 #include "artdaq/ArtModules/ArtdaqOutput.hh"
4 #include "artdaq/ArtModules/ArtdaqSharedMemoryService.h"
5 #include "artdaq/DAQdata/Globals.hh"
6 #include "artdaq/DAQdata/NetMonHeader.hh"
7 #include "artdaq/DAQrate/DataSenderManager.hh"
8 
9 // if TRACE_NAME has varible, it is safest to define after includes
10 #define TRACE_NAME (app_name + "_RootNetOutput").c_str()
11 
12 #define DUMP_SEND_MESSAGE 0
13 
14 namespace art {
15 class RootNetOutput;
16 }
17 
24 {
25 public:
33  explicit RootNetOutput(fhicl::ParameterSet const& ps);
34 
39 
44  size_t dataReceiverCount() const { return sender_ptr_->destinationCount(); }
45 
46 protected:
51  virtual void SendMessage(artdaq::FragmentPtr& fragment);
52 
53 private:
54  void connect();
55  void disconnect();
56 
57  std::unique_ptr<artdaq::DataSenderManager> sender_ptr_;
58  fhicl::ParameterSet data_pset_;
59  double init_timeout_s_;
60 };
61 
62 art::RootNetOutput::RootNetOutput(fhicl::ParameterSet const& ps)
63  : ArtdaqOutput(ps)
64  , sender_ptr_(nullptr)
65  , data_pset_(ps)
66 {
67  TLOG(TLVL_DEBUG) << "Begin: RootNetOutput::RootNetOutput(ParameterSet const& ps)";
68  // Make sure the ArtdaqSharedMemoryService is available
69  art::ServiceHandle<ArtdaqSharedMemoryServiceInterface> shm;
70  init_timeout_s_ = ps.get<double>("init_fragment_timeout_seconds", 1.0);
71  connect();
72  TLOG(TLVL_DEBUG) << "End: RootNetOutput::RootNetOutput(ParameterSet const& ps)";
73 }
74 
76 {
77  TLOG(TLVL_DEBUG) << "Begin: RootNetOutput::~RootNetOutput()";
78  disconnect();
79  TLOG(TLVL_DEBUG) << "End: RootNetOutput::~RootNetOutput()";
80 }
81 
82 void art::RootNetOutput::SendMessage(artdaq::FragmentPtr& fragment)
83 {
84  //
85  // Send message.
86  //
87  {
88  TLOG(TLVL_WRITE) << "RootNetOutput::SendMessage Sending a message with type code "
89  << artdaq::detail::RawFragmentHeader::SystemTypeToString(fragment->type());
90  if (sender_ptr_ == nullptr)
91  {
92  TLOG(TLVL_DEBUG) << "Reconnecting DataSenderManager";
93  connect();
94  }
95 
96 #if DUMP_SEND_MESSAGE
97  std::string fileName = "sendMessage_" + std::to_string(my_rank) + "_" + std::to_string(getpid()) + "_" +
98  std::to_string(sequenceId) + ".bin";
99  std::fstream ostream(fileName, std::ios::out | std::ios::binary);
100  ostream.write(msg.Buffer(), msg.Length());
101  ostream.close();
102 #endif
103 
104  auto sequenceId = fragment->sequenceID();
105  TLOG(TLVL_DEBUG) << "Sending message with sequenceID=" << sequenceId << ", type=" << fragment->type()
106  << ", length=" << fragment->dataSizeBytes();
107 
108  sender_ptr_->sendFragment(std::move(*fragment));
109  // Events are unique in art, so this will be the only send with this sequence ID!
110  sender_ptr_->RemoveRoutingTableEntry(sequenceId);
111  TLOG(TLVL_WRITE) << "RootNetOutput::SendMessage: Message sent.";
112  }
113 }
114 
115 void art::RootNetOutput::connect()
116 {
117  auto start_time = std::chrono::steady_clock::now();
118 
119  char const* artapp_env = getenv("ARTDAQ_RANK");
120  if (artapp_env != NULL && my_rank < 0)
121  my_rank = std::atoi(artapp_env);
122 
123  while (my_rank == -1 && artdaq::TimeUtils::GetElapsedTime(start_time) < init_timeout_s_)
124  {
125  usleep(1000);
126  }
127  sender_ptr_.reset(new artdaq::DataSenderManager(data_pset_));
128 }
129 
130 void art::RootNetOutput::disconnect()
131 {
132  if (sender_ptr_) sender_ptr_.reset(nullptr);
133 }
134 
135 DEFINE_ART_MODULE(art::RootNetOutput)
Sends Fragment objects using TransferInterface plugins. Uses Routing Tables if confgiured, otherwise will Round-Robin Fragments to the destinations.
This is the base class for artdaq OutputModules, providing the serialization interface for art Events...
~RootNetOutput()
RootNetOutput Destructor.
virtual void SendMessage(artdaq::FragmentPtr &fragment)
Send a message using DataSenderManager
size_t dataReceiverCount() const
Get the number of data receivers.
An art::OutputModule which sends events using DataSenderManager. This module is designed for transpor...
RootNetOutput(fhicl::ParameterSet const &ps)
RootNetOutput Constructor.