artdaq  v3_00_02
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  run_is_paused_.store(false);
123  return true;
124 }
125 
127 {
128  logMessage_("Pausing run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
129  ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
130  pause_requested_.store(true);
131 
132  bool endSucceeded = false;
133  int attemptsToEnd = 1;
134  endSucceeded = event_store_ptr_->endSubrun();
135  while (!endSucceeded && attemptsToEnd < 3)
136  {
137  ++attemptsToEnd;
138  TLOG_DEBUG(app_name) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
139  endSucceeded = event_store_ptr_->endSubrun();
140  }
141  if (!endSucceeded)
142  {
143  TLOG_ERROR(app_name)
144  << "EventStore::endSubrun in pause method failed after three tries." << TLOG_ENDL;
145  }
146 
147  run_is_paused_.store(true);
148  return true;
149 }
150 
152 {
153  logMessage_("Resuming run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
154  pause_requested_.store(false);
155  metricMan_.do_start();
156  event_store_ptr_->startSubrun();
157  run_is_paused_.store(false);
158  return true;
159 }
160 
162 {
163  /* We don't care about flushing data here. The only way to transition to the
164  shutdown state is from a state where there is no data taking. All we have
165  to do is signal the art input module that we're done taking data so that
166  it can wrap up whatever it needs to do. */
167 
168  TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down DataReceiverManager" << TLOG_ENDL;
169  receiver_ptr_.reset(nullptr);
170 
171  bool endSucceeded = false;
172  int attemptsToEnd = 1;
173  TLOG_DEBUG("DataReceiverCore") << "shutdown: Calling EventStore::endOfData" << TLOG_ENDL;
174  endSucceeded = event_store_ptr_->endOfData();
175  while (!endSucceeded && attemptsToEnd < 3)
176  {
177  ++attemptsToEnd;
178  TLOG_DEBUG(app_name) << "Retrying EventStore::endOfData()" << TLOG_ENDL;
179  endSucceeded = event_store_ptr_->endOfData();
180  }
181 
182  TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down SharedMemoryEventManager" << TLOG_ENDL;
183  event_store_ptr_.reset();
184 
185  TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down MetricManager" << TLOG_ENDL;
186  metricMan_.shutdown();
187 
188  TLOG_DEBUG("DataReceiverCore") << "shutdown: Complete" << TLOG_ENDL;
189  return endSucceeded;
190 }
191 
192 bool artdaq::DataReceiverCore::soft_initialize(fhicl::ParameterSet const& pset)
193 {
194  TLOG_DEBUG(app_name) << "soft_initialize method called with DAQ "
195  << "ParameterSet = \"" << pset.to_string()
196  << "\"." << TLOG_ENDL;
197  return true;
198 }
199 
200 bool artdaq::DataReceiverCore::reinitialize(fhicl::ParameterSet const& pset)
201 {
202  TLOG_DEBUG(app_name) << "reinitialize method called with DAQ "
203  << "ParameterSet = \"" << pset.to_string()
204  << "\"." << TLOG_ENDL;
205  event_store_ptr_ = nullptr;
206  return initialize(pset);
207 }
208 
209 std::string artdaq::DataReceiverCore::report(std::string const& which) const
210 {
211  if (which == "incomplete_event_count")
212  {
213  if (event_store_ptr_ != nullptr)
214  {
215  return boost::lexical_cast<std::string>(event_store_ptr_->GetIncompleteEventCount());
216  }
217  else
218  {
219  return "-1";
220  }
221  }
222  if (which == "event_count")
223  {
224  if (receiver_ptr_ != nullptr)
225  return boost::lexical_cast<std::string>(receiver_ptr_->GetReceivedFragmentCount()->count());
226 
227  return "0";
228  }
229 
230  // lots of cool stuff that we can do here
231  // - report on the number of fragments received and the number
232  // of events built (in the current or previous run
233  // - report on the number of incomplete events in the EventStore
234  // (if running)
235  std::string tmpString;
236  if (event_store_ptr_ != nullptr) tmpString.append(app_name + " run number = " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) + ".\n");
237  tmpString.append("Command \"" + which + "\" is not currently supported.");
238  return tmpString;
239 }
240 
241 void artdaq::DataReceiverCore::logMessage_(std::string const& text)
242 {
243  if (verbose_)
244  {
245  TLOG_INFO(app_name) << text << TLOG_ENDL;
246  }
247  else
248  {
249  TLOG_DEBUG(app_name) << text << TLOG_ENDL;
250  }
251 }
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.