artdaq  v3_00_01
DataReceiverCore.cc
1 #include "canvas/Utilities/Exception.h"
2 #include "art/Framework/Art/artapp.h"
3 
4 #define TRACE_NAME "DataReceiverCore"
5 #include "artdaq/DAQdata/Globals.hh"
6 #include "artdaq-core/Core/SimpleMemoryReader.hh"
7 #include "artdaq-core/Utilities/ExceptionHandler.hh"
8 
9 #include "artdaq/Application/DataReceiverCore.hh"
10 #include "artdaq/TransferPlugins/TransferInterface.hh"
11 
12 #include <iomanip>
13 
14 artdaq::DataReceiverCore::DataReceiverCore(int rank, std::string name)
15  : name_(name)
16  , stop_requested_(false)
17  , pause_requested_(false)
18  , run_is_paused_(false)
19 {
20  TLOG_DEBUG(name_) << "Constructor" << TLOG_ENDL;
21  my_rank = rank;
22  metricMan = &metricMan_;
23 }
24 
26 {
27  TLOG_DEBUG(name_) << "Destructor" << TLOG_ENDL;
28 }
29 
30 bool artdaq::DataReceiverCore::initializeDataReceiver(fhicl::ParameterSet const& pset, fhicl::ParameterSet const& data_pset, fhicl::ParameterSet const& metric_pset)
31 {
32  // other parameters
33  verbose_ = pset.get<bool>("verbose", false);
34 
35  if (metric_pset.is_empty())
36  {
37  TLOG_INFO(name_) << "No metric plugins appear to be defined" << TLOG_ENDL;
38  }
39  try
40  {
41  metricMan_.initialize(metric_pset, name_ + "." + std::to_string(my_rank));
42  }
43  catch (...)
44  {
45  ExceptionHandler(ExceptionHandlerRethrow::no,
46  "Error loading metrics in DataReceiverCore::initialize()");
47  }
48 
49  fhicl::ParameterSet tmp = pset;
50  tmp.erase("daq");
51 
52  fhicl::ParameterSet data_tmp = data_pset;
53  if (data_pset.has_key("expected_events_per_bunch"))
54  {
55  data_tmp.put<int>("expected_fragments_per_event", data_pset.get<int>("expected_events_per_bunch"));
56  }
57 
58  event_store_ptr_.reset(new SharedMemoryEventManager(data_tmp, tmp));
59 
60  receiver_ptr_.reset(new artdaq::DataReceiverManager(data_tmp, event_store_ptr_));
61 
62  return true;
63 }
64 
66 {
67  stop_requested_.store(false);
68  pause_requested_.store(false);
69  run_is_paused_.store(false);
70  metricMan_.do_start();
71  event_store_ptr_->startRun(id.run());
72  receiver_ptr_->start_threads();
73 
74  logMessage_("Started run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
75  return true;
76 }
77 
79 {
80  logMessage_("Stopping run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
81  ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
82  bool endSucceeded;
83  int attemptsToEnd;
84 
85  // 21-Jun-2013, KAB - the stop_requested_ variable must be set
86  // before the flush lock so that the processFragments loop will
87  // exit (after the timeout), the lock will be released (in the
88  // processFragments method), and this method can continue.
89  stop_requested_.store(true);
90 
91  if (!run_is_paused_.load())
92  {
93  endSucceeded = false;
94  attemptsToEnd = 1;
95  endSucceeded = event_store_ptr_->endSubrun();
96  while (!endSucceeded && attemptsToEnd < 3)
97  {
98  ++attemptsToEnd;
99  TLOG_DEBUG(name_) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
100  endSucceeded = event_store_ptr_->endSubrun();
101  }
102  if (!endSucceeded)
103  {
104  TLOG_ERROR(name_)
105  << "EventStore::endSubrun in stop method failed after three tries." << TLOG_ENDL;
106  }
107  }
108 
109  endSucceeded = false;
110  attemptsToEnd = 1;
111  endSucceeded = event_store_ptr_->endRun();
112  while (!endSucceeded && attemptsToEnd < 3)
113  {
114  ++attemptsToEnd;
115  TLOG_DEBUG(name_) << "Retrying EventStore::endRun()" << TLOG_ENDL;
116  endSucceeded = event_store_ptr_->endRun();
117  }
118  if (!endSucceeded)
119  {
120  TLOG_ERROR(name_)
121  << "EventStore::endRun in stop method failed after three tries." << TLOG_ENDL;
122  }
123 
124  run_is_paused_.store(false);
125  return true;
126 }
127 
129 {
130  logMessage_("Pausing run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
131  ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
132  pause_requested_.store(true);
133 
134  bool endSucceeded = false;
135  int attemptsToEnd = 1;
136  endSucceeded = event_store_ptr_->endSubrun();
137  while (!endSucceeded && attemptsToEnd < 3)
138  {
139  ++attemptsToEnd;
140  TLOG_DEBUG(name_) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
141  endSucceeded = event_store_ptr_->endSubrun();
142  }
143  if (!endSucceeded)
144  {
145  TLOG_ERROR(name_)
146  << "EventStore::endSubrun in pause method failed after three tries." << TLOG_ENDL;
147  }
148 
149  run_is_paused_.store(true);
150  return true;
151 }
152 
154 {
155  logMessage_("Resuming run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
156  pause_requested_.store(false);
157  metricMan_.do_start();
158  event_store_ptr_->startSubrun();
159  run_is_paused_.store(false);
160  return true;
161 }
162 
164 {
165  /* We don't care about flushing data here. The only way to transition to the
166  shutdown state is from a state where there is no data taking. All we have
167  to do is signal the art input module that we're done taking data so that
168  it can wrap up whatever it needs to do. */
169 
170  TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down DataReceiverManager" << TLOG_ENDL;
171  receiver_ptr_.reset(nullptr);
172 
173  bool endSucceeded = false;
174  int attemptsToEnd = 1;
175  TLOG_DEBUG("DataReceiverCore") << "shutdown: Calling EventStore::endOfData" << TLOG_ENDL;
176  endSucceeded = event_store_ptr_->endOfData();
177  while (!endSucceeded && attemptsToEnd < 3)
178  {
179  ++attemptsToEnd;
180  TLOG_DEBUG(name_) << "Retrying EventStore::endOfData()" << TLOG_ENDL;
181  endSucceeded = event_store_ptr_->endOfData();
182  }
183 
184  TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down SharedMemoryEventManager" << TLOG_ENDL;
185  event_store_ptr_.reset();
186 
187  TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down MetricManager" << TLOG_ENDL;
188  metricMan_.shutdown();
189 
190  TLOG_DEBUG("DataReceiverCore") << "shutdown: Complete" << TLOG_ENDL;
191  return endSucceeded;
192 }
193 
194 bool artdaq::DataReceiverCore::soft_initialize(fhicl::ParameterSet const& pset)
195 {
196  TLOG_DEBUG(name_) << "soft_initialize method called with DAQ "
197  << "ParameterSet = \"" << pset.to_string()
198  << "\"." << TLOG_ENDL;
199  return true;
200 }
201 
202 bool artdaq::DataReceiverCore::reinitialize(fhicl::ParameterSet const& pset)
203 {
204  TLOG_DEBUG(name_) << "reinitialize method called with DAQ "
205  << "ParameterSet = \"" << pset.to_string()
206  << "\"." << TLOG_ENDL;
207  event_store_ptr_ = nullptr;
208  return initialize(pset);
209 }
210 
211 std::string artdaq::DataReceiverCore::report(std::string const& which) const
212 {
213  if (which == "incomplete_event_count")
214  {
215  if (event_store_ptr_ != nullptr)
216  {
217  return boost::lexical_cast<std::string>(event_store_ptr_->GetIncompleteEventCount());
218  }
219  else
220  {
221  return "-1";
222  }
223  }
224  if (which == "event_count")
225  {
226  if (receiver_ptr_ != nullptr)
227  return boost::lexical_cast<std::string>(receiver_ptr_->GetReceivedFragmentCount()->count());
228 
229  return "0";
230  }
231 
232  // lots of cool stuff that we can do here
233  // - report on the number of fragments received and the number
234  // of events built (in the current or previous run
235  // - report on the number of incomplete events in the EventStore
236  // (if running)
237  std::string tmpString;
238  if (event_store_ptr_ != nullptr) tmpString.append(name_ + " run number = " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) + ".\n");
239  tmpString.append("Command \"" + which + "\" is not currently supported.");
240  return tmpString;
241 }
242 
243 void artdaq::DataReceiverCore::logMessage_(std::string const& text)
244 {
245  if (verbose_)
246  {
247  TLOG_INFO(name_) << text << TLOG_ENDL;
248  }
249  else
250  {
251  TLOG_DEBUG(name_) << text << TLOG_ENDL;
252  }
253 }
MetricManager metricMan_
MetricManager concrete instance (for Globals.hh::metricMan)
bool soft_initialize(fhicl::ParameterSet const &pset)
Soft-Initializes the DataReceiverCore. No-Op.
The SharedMemoryEventManager is a SharedMemoryManger which tracks events as they are built...
bool resume()
Resumes the DataReceiverCore.
bool shutdown()
Shuts Down the DataReceiverCore.
bool start(art::RunID id)
Start the DataReceiverCore.
void logMessage_(std::string const &text)
Log a message, setting severity based on verbosity flag.
bool stop()
Stops the DataReceiverCore.
std::string report(std::string const &which) const
Send a report on a given run-time quantity.
std::string name_
Name of this DataReceiverCore instance.
bool pause()
Pauses the DataReceiverCore.
Receives Fragment objects from one or more DataSenderManager instances using TransferInterface plugin...
bool initializeDataReceiver(fhicl::ParameterSet const &pset, fhicl::ParameterSet const &data_pset, fhicl::ParameterSet const &metric_pset)
Initialize the DataReceiverCore (should be called from initialize() overrides.
DataReceiverCore(int rank, std::string name)
DataReceiverCore Constructor.
bool reinitialize(fhicl::ParameterSet const &pset)
Reinitializes the DataReceiverCore.