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