otsdaq  v2_04_01
DataManager.cc
1 #include "otsdaq-core/DataManager/DataManager.h"
2 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
3 #include "otsdaq-core/DataManager/CircularBuffer.h"
4 #include "otsdaq-core/DataManager/DataConsumer.h"
5 #include "otsdaq-core/DataManager/DataProducerBase.h"
6 #include "otsdaq-core/Macros/CoutMacros.h"
7 #include "otsdaq-core/MessageFacility/MessageFacility.h"
8 #include "otsdaq-core/PluginMakers/MakeDataProcessor.h"
9 
10 /*
11 #include "otsdaq-core/TablePlugins/ARTDAQConsumerTable.h"
12 #include "otsdaq-core/TablePlugins/DataBufferTable.h"
13 #include "otsdaq-core/TablePlugins/DataManagerTable.h"
14 #include
15 "otsdaq-core/TablePlugins/UDPDataListenerProducerTable.h"
16 #include "otsdaq-core/DataProcessorPlugins/ARTDAQConsumer.h"
17 #include "otsdaq-core/DataProcessorPlugins/DQMHistosConsumer.h"
18 #include "otsdaq-core/DataProcessorPlugins/DataListenerProducer.h"
19 #include "otsdaq-core/DataProcessorPlugins/DataStreamer.h"
20 #include "otsdaq-core/DataProcessorPlugins/RawDataSaverConsumer.h"
21 #include "otsdaq-core/EventBuilder/AssociativeMemoryEventBuilder.h"
22 #include "otsdaq-core/EventBuilder/Event.h"
23 #include "otsdaq-core/EventBuilder/EventDataSaver.h"
24 */
25 
26 #include <unistd.h> //usleep
27 #include <iostream>
28 #include <vector>
29 
30 using namespace ots;
31 
32 //========================================================================================================================
33 DataManager::DataManager(const ConfigurationTree& theXDAQContextConfigTree,
34  const std::string& supervisorConfigurationPath)
35  : Configurable(theXDAQContextConfigTree, supervisorConfigurationPath)
36  , parentSupervisorHasFrontends_(false)
37 {
38  __CFG_COUT__ << "Constructed." << __E__;
39 } // end constructor
40 
41 //========================================================================================================================
42 DataManager::~DataManager(void)
43 {
44  __CFG_COUT__ << "Destructor." << __E__;
45  DataManager::destroyBuffers();
46  __CFG_COUT__ << "Destructed." << __E__;
47 } // end destructor
48 
49 //========================================================================================================================
50 void DataManager::dumpStatus(std::ostream* out) const
51 {
52  *out << "Buffer count: " << buffers_.size() << __E__;
53  for(auto& bufferPair : buffers_)
54  {
55  *out << "\t"
56  << "Buffer '" << bufferPair.first << "' status=" << bufferPair.second.status_
57  << " producers=" << bufferPair.second.producers_.size()
58  << " consumers=" << bufferPair.second.consumers_.size() << __E__;
59 
60  *out << "\t\t"
61  << "Producers:" << __E__;
62  for(auto& producer : bufferPair.second.producers_)
63  {
64  *out << "\t\t\t" << producer->getProcessorID() << " ["
65  << bufferPair.second.buffer_->getProducerBufferSize(
66  producer->getProcessorID())
67  << "]" << __E__;
68  }
69  *out << "\t\t"
70  << "Consumers:" << __E__;
71  for(auto& consumer : bufferPair.second.consumers_)
72  {
73  *out << "\t\t\t" << consumer->getProcessorID() << __E__;
74  }
75  }
76 } // end dumpStatus()
77 
78 //========================================================================================================================
79 void DataManager::configure(void)
80 {
81  const std::string transitionName = "Configuring";
82 
83  const std::string COL_NAME_bufferGroupLink = "LinkToDataBufferTable";
84  const std::string COL_NAME_processorGroupLink = "LinkToDataProcessorTable";
85  const std::string COL_NAME_processorType = "ProcessorType";
86  const std::string COL_NAME_processorPlugin = "ProcessorPluginName";
87  const std::string COL_NAME_processorLink = "LinkToProcessorTable";
88  const std::string COL_NAME_appUID = "ApplicationUID";
89 
90  __CFG_COUT__ << transitionName << " DataManager" << __E__;
91  __CFG_COUT__ << "Path: " << theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink
92  << __E__;
93 
94  destroyBuffers();
95 
96  // get all buffer definitions from configuration tree
97  for(const auto& buffer :
98  theXDAQContextConfigTree_
99  .getNode(theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink)
100  .getChildren()) //"/LinkToDataManagerTable").getChildren())
101  {
102  __CFG_COUT__ << "Data Buffer Name: " << buffer.first << __E__;
103  if(buffer.second.getNode(TableViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
104  {
105  std::vector<unsigned int> producersVectorLocation;
106  std::vector<unsigned int> consumersVectorLocation;
107  auto bufferConfigurationList =
108  buffer.second.getNode(COL_NAME_processorGroupLink)
109  .getChildren(); //"LinkToDataBufferTable").getChildren();
110  unsigned int location = 0;
111  for(const auto& bufferConfiguration : bufferConfigurationList)
112  {
113  __CFG_COUT__ << "Processor id: " << bufferConfiguration.first << __E__;
114  if(bufferConfiguration.second
115  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
116  .getValue<bool>())
117  {
118  if(bufferConfiguration.second.getNode(COL_NAME_processorType)
119  .getValue<std::string>() == "Producer")
120  {
121  producersVectorLocation.push_back(location);
122  }
123  else if(bufferConfiguration.second.getNode(COL_NAME_processorType)
124  .getValue<std::string>() == "Consumer")
125  {
126  consumersVectorLocation.push_back(location);
127  }
128  else
129  {
130  __CFG_SS__ << "Node ProcessorType in "
131  << bufferConfiguration.first << " of type "
132  << bufferConfiguration.second
133  .getNode(COL_NAME_processorPlugin)
134  .getValue<std::string>()
135  << " is invalid. The only accepted types are Producer "
136  "and Consumer"
137  << __E__;
138  __CFG_MOUT_ERR__ << ss.str();
139  __CFG_SS_THROW__;
140  }
141  }
142  ++location;
143 
144  } // end loop sorting by producer and consumer
145 
146  if(!parentSupervisorHasFrontends_ &&
147  producersVectorLocation.size() ==
148  0) // || consumersVectorLocation.size() == 0)
149  {
150  __CFG_SS__ << "Node Data Buffer " << buffer.first << " has "
151  << producersVectorLocation.size() << " Producers"
152  << " and " << consumersVectorLocation.size() << " Consumers"
153  << " there must be at least 1 Producer "
154  << // of both configured
155  "for the buffer!" << __E__;
156  __CFG_MOUT_ERR__ << ss.str();
157  __CFG_SS_THROW__;
158  }
159 
160  if(parentSupervisorHasFrontends_)
161  __CFG_COUT__
162  << "Parent supervisor has front-ends, so FE-producers may "
163  << "be instantiated in the configure steps of the FESupervisor."
164  << __E__;
165 
166  configureBuffer<std::string, std::map<std::string, std::string> >(
167  buffer.first);
168 
169  for(auto& producerLocation : producersVectorLocation)
170  {
171  // __CFG_COUT__ << theConfigurationPath_ << __E__;
172  // __CFG_COUT__ << buffer.first << __E__;
173  __CFG_COUT__ << "Creating producer... "
174  << bufferConfigurationList[producerLocation].first << __E__;
175  // __CFG_COUT__ <<
176  // bufferConfigurationMap[producer].getNode(COL_NAME_processorPlugin).getValue<std::string>()
177  //<< __E__;
178  // __CFG_COUT__ <<
179  // bufferConfigurationMap[producer].getNode("LinkToProcessorTable") <<
180  // __E__;
181  // __CFG_COUT__ << "THIS DATA MANAGER POINTER: " << this <<
182  // __E__;
183  // __CFG_COUT__ << "PASSED" << __E__;
184 
185  try
186  {
187  // buffers_[buffer.first].producers_.push_back(std::shared_ptr<DataProducerBase>(
188  DataProducerBase* tmpCastCheck =
189  dynamic_cast<DataProducerBase*>(makeDataProcessor(
190  bufferConfigurationList[producerLocation]
191  .second.getNode(COL_NAME_processorPlugin)
192  .getValue<std::string>(),
193  theXDAQContextConfigTree_.getBackNode(theConfigurationPath_)
194  .getNode(COL_NAME_appUID)
195  .getValue<std::string>(),
196  buffer.first,
197  bufferConfigurationList[producerLocation].first,
198  theXDAQContextConfigTree_,
199  theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink + "/" +
200  buffer.first + "/" + COL_NAME_processorGroupLink + "/" +
201  bufferConfigurationList[producerLocation].first + "/" +
202  COL_NAME_processorLink)); //));
203 
204  if(!tmpCastCheck)
205  {
206  __CFG_SS__ << "Construction failed for producer '"
207  << bufferConfigurationList[producerLocation].first
208  << "!' Null pointer returned." << __E__;
209  __CFG_SS_THROW__;
210  }
211  __CFG_COUT__ << tmpCastCheck->getProcessorID() << __E__;
212 
213  {
214  __CFG_SS__;
215  dumpStatus((std::ostream*)&ss);
216  __CFG_COUT__ << ss.str() << __E__;
217  }
218  }
219  catch(const std::bad_cast& e)
220  {
221  __CFG_SS__ << "Failed to instantiate producer plugin named '"
222  << bufferConfigurationList[producerLocation].first
223  << "' of type '"
224  << bufferConfigurationList[producerLocation]
225  .second.getNode(COL_NAME_processorPlugin)
226  .getValue<std::string>()
227  << "' due to the following error: \n"
228  << e.what() << __E__;
229  __CFG_MOUT_ERR__ << ss.str();
230  __CFG_SS_THROW__;
231  }
232  catch(const cet::exception& e)
233  {
234  __CFG_SS__ << "Failed to instantiate producer plugin named '"
235  << bufferConfigurationList[producerLocation].first
236  << "' of type '"
237  << bufferConfigurationList[producerLocation]
238  .second.getNode(COL_NAME_processorPlugin)
239  .getValue<std::string>()
240  << "' due to the following error: \n"
241  << e.what() << __E__;
242  __CFG_MOUT_ERR__ << ss.str();
243  __CFG_SS_THROW__;
244  }
245  catch(const std::runtime_error& e)
246  {
247  __CFG_SS__ << "Failed to instantiate producer plugin named '"
248  << bufferConfigurationList[producerLocation].first
249  << "' of type '"
250  << bufferConfigurationList[producerLocation]
251  .second.getNode(COL_NAME_processorPlugin)
252  .getValue<std::string>()
253  << "' due to the following error: \n"
254  << e.what() << __E__;
255  __CFG_MOUT_ERR__ << ss.str();
256  __CFG_SS_THROW__;
257  }
258  catch(...)
259  {
260  __CFG_SS__ << "Failed to instantiate producer plugin named '"
261  << bufferConfigurationList[producerLocation].first
262  << "' of type '"
263  << bufferConfigurationList[producerLocation]
264  .second.getNode(COL_NAME_processorPlugin)
265  .getValue<std::string>()
266  << "' due to an unknown error." << __E__;
267  __CFG_MOUT_ERR__ << ss.str();
268  throw; // if we do not throw, it is hard to tell what is causing the
269  // problem..
270  //__CFG_SS_THROW__;
271  }
272  __CFG_COUT__ << bufferConfigurationList[producerLocation].first
273  << " has been created!" << __E__;
274  } // end producer creation loop
275 
276  for(auto& consumerLocation : consumersVectorLocation)
277  {
278  // __CFG_COUT__ << theConfigurationPath_ << __E__;
279  // __CFG_COUT__ << buffer.first << __E__;
280  __CFG_COUT__ << "Creating consumer... "
281  << bufferConfigurationList[consumerLocation].first << __E__;
282  // __CFG_COUT__ <<
283  // bufferConfigurationMap[consumer].getNode(COL_NAME_processorPlugin).getValue<std::string>()
284  //<< __E__;
285  // __CFG_COUT__ <<
286  // bufferConfigurationMap[consumer].getNode("LinkToProcessorTable") <<
287  // __E__;
288  // __CFG_COUT__ <<
289  // theXDAQContextConfigTree_.getBackNode(theConfigurationPath_) <<
290  // __E__;
291  // __CFG_COUT__ << "THIS DATA MANAGER POINTER: " << this <<
292  // __E__;
293  // __CFG_COUT__ << "PASSED" << __E__;
294  try
295  {
296  // buffers_[buffer.first].consumers_.push_back(std::shared_ptr<DataConsumer>(
297  DataConsumer* tmpCastCheck =
298  dynamic_cast<DataConsumer*>(makeDataProcessor(
299  bufferConfigurationList[consumerLocation]
300  .second.getNode(COL_NAME_processorPlugin)
301  .getValue<std::string>(),
302  theXDAQContextConfigTree_.getBackNode(theConfigurationPath_)
303  .getNode(COL_NAME_appUID)
304  .getValue<std::string>(),
305  buffer.first,
306  bufferConfigurationList[consumerLocation].first,
307  theXDAQContextConfigTree_,
308  theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink + "/" +
309  buffer.first + "/" + COL_NAME_processorGroupLink + "/" +
310  bufferConfigurationList[consumerLocation].first + "/" +
311  COL_NAME_processorLink)); //));
312 
313  if(!tmpCastCheck)
314  {
315  __CFG_SS__ << "Construction failed for consumer '"
316  << bufferConfigurationList[consumerLocation].first
317  << "!' Null pointer returned." << __E__;
318  __CFG_SS_THROW__;
319  }
320 
321  {
322  __CFG_SS__;
323  dumpStatus((std::ostream*)&ss);
324  __CFG_COUT__ << ss.str() << __E__;
325  }
326  }
327  catch(const std::bad_cast& e)
328  {
329  __CFG_SS__ << "Failed to instantiate consumer plugin named '"
330  << bufferConfigurationList[consumerLocation].first
331  << "' of type '"
332  << bufferConfigurationList[consumerLocation]
333  .second.getNode(COL_NAME_processorPlugin)
334  .getValue<std::string>()
335  << "' due to the following error: \n"
336  << e.what() << __E__;
337  __CFG_MOUT_ERR__ << ss.str();
338  __CFG_SS_THROW__;
339  }
340  catch(const cet::exception& e)
341  {
342  __CFG_SS__ << "Failed to instantiate consumer plugin named '"
343  << bufferConfigurationList[consumerLocation].first
344  << "' of type '"
345  << bufferConfigurationList[consumerLocation]
346  .second.getNode(COL_NAME_processorPlugin)
347  .getValue<std::string>()
348  << "' due to the following error: \n"
349  << e.what() << __E__;
350  __CFG_MOUT_ERR__ << ss.str();
351  __CFG_SS_THROW__;
352  }
353  catch(const std::runtime_error& e)
354  {
355  __CFG_SS__ << "Failed to instantiate consumer plugin named '"
356  << bufferConfigurationList[consumerLocation].first
357  << "' of type '"
358  << bufferConfigurationList[consumerLocation]
359  .second.getNode(COL_NAME_processorPlugin)
360  .getValue<std::string>()
361  << "' due to the following error: \n"
362  << e.what() << __E__;
363  __CFG_MOUT_ERR__ << ss.str();
364  __CFG_SS_THROW__;
365  }
366  catch(...)
367  {
368  __CFG_SS__ << "Failed to instantiate consumer plugin named '"
369  << bufferConfigurationList[consumerLocation].first
370  << "' of type '"
371  << bufferConfigurationList[consumerLocation]
372  .second.getNode(COL_NAME_processorPlugin)
373  .getValue<std::string>()
374  << "' due to an unknown error." << __E__;
375  __CFG_MOUT_ERR__ << ss.str();
376  throw; // if we do not throw, it is hard to tell what is happening..
377  //__CFG_SS_THROW__;
378  }
379  __CFG_COUT__ << bufferConfigurationList[consumerLocation].first
380  << " has been created!" << __E__;
381  } // end consumer creation loop
382  }
383  }
384 } // end configure()
385 
386 //========================================================================================================================
387 void DataManager::halt(void)
388 {
389  const std::string transitionName = "Halting";
390 
391  __CFG_COUT__ << transitionName << " DataManager " << __E__;
392 
393  // since halting also occurs on errors, ignore more errors
394  try
395  {
396  stop();
397  }
398  catch(...)
399  {
400  __CFG_COUT_WARN__ << "An error occurred while halting the Data Manager, ignoring."
401  << __E__;
402  }
403 
404  stop();
405 
406  __CFG_COUT__ << transitionName << " DataManager stopped. Now destruct buffers..."
407  << __E__;
408 
409  DataManager::destroyBuffers(); // Stop all Buffers, deletes all pointers, and delete
410  // Buffer struct
411 } // end halt()
412 
413 //========================================================================================================================
414 void DataManager::pause(void)
415 {
416  const std::string transitionName = "Pausing";
417 
418  __CFG_COUT__ << transitionName << " DataManager " << __E__;
419 
420  DataManager::pauseAllBuffers();
421 } // end pause()
422 
423 //========================================================================================================================
424 void DataManager::resume(void)
425 {
426  const std::string transitionName = "Resuming";
427 
428  __CFG_COUT__ << transitionName << " DataManager " << __E__;
429 
430  DataManager::resumeAllBuffers();
431 } // end resume()
432 
433 //========================================================================================================================
434 void DataManager::start(std::string runNumber)
435 {
436  const std::string transitionName = "Starting";
437 
438  __CFG_COUT__ << transitionName << " DataManager " << __E__;
439 
440  DataManager::startAllBuffers(runNumber);
441 } // end start()
442 
443 //========================================================================================================================
444 void DataManager::stop()
445 {
446  const std::string transitionName = "Stopping";
447 
448  __CFG_COUT__ << transitionName << " DataManager " << __E__;
449 
450  DataManager::stopAllBuffers();
451 } // end stop()
452 
453 //========================================================================================================================
454 // destroyBuffers
455 // Stop all Buffers, deletes all pointers, and delete Buffer struct
456 void DataManager::destroyBuffers(void)
457 {
458  DataManager::stopAllBuffers();
459 
460  for(auto& bufferPair : buffers_)
461  {
462  // delete all producers/consumers
463  // then delete CircularBuffer
464  for(auto& producer : bufferPair.second.producers_)
465  delete producer;
466  bufferPair.second.producers_.clear();
467 
468  for(auto& consumer : bufferPair.second.consumers_)
469  delete consumer;
470  bufferPair.second.consumers_.clear();
471 
472  delete bufferPair.second.buffer_;
473  } // end delete buffer loop
474 
475  buffers_.clear();
476 } // end destroyBuffers()
477 
479 // void DataManager::eraseBuffer(const std::string& bufferUID)
480 //{
481 // if (deleteBuffer(bufferUID))
482 // buffers_.erase(bufferUID);
483 //} //end eraseBuffer()
484 //
486 //
487 // bool DataManager::deleteBuffer(const std::string& bufferUID)
488 //{
489 // auto it = buffers_.find(bufferUID);
490 // if (it != buffers_.end())
491 // {
492 // auto aBuffer = it->second;
493 // if (aBuffer.status_ == Running)
494 // stopBuffer(bufferUID);
495 //
501 // aBuffer.consumers_.clear();
502 // // for(auto& itp: aBuffer.producers_)
503 // // delete itp;
504 // aBuffer.producers_.clear();
505 //
506 // delete aBuffer.buffer_;
507 // return true;
508 // }
509 // return false;
510 //} //end deleteBuffer()
511 //
518 // void DataManager::unregisterConsumer(const std::string& bufferID, const std::string&
519 // consumerID)
520 //{
521 // __CFG_COUT__ << "Un-Registering consumer '" << consumerID <<
522 // "' from buffer '" << bufferID << "'..." << __E__;
523 //
524 // auto bufferIt = buffers_.find(bufferID);
525 // if(bufferIt == buffers_.end())
526 // {
527 // __CFG_SS__ << "While Un-Registering consumer '" << consumerID <<
528 // ",' buffer '" << bufferID << "' not found!" << __E__;
529 // __CFG_SS_THROW__;
530 // }
531 //
532 // //just destroy consumer, and it unregisters itself
533 // for (auto consumerIt = bufferIt->second.consumers_.begin();
534 // consumerIt != bufferIt->second.consumers_.end(); consumerIt++)
535 // {
536 // if((*consumerIt)->getProcessorID() == consumerID)
537 // {
538 // bufferIt->second.consumers_.erase(consumerIt);
539 // break;
540 // }
541 // }
542 // //DO NOT DO ANY STRING BASED UNREGISTERING.. leave it to end of DataManager halt
543 // //bufferIt->second.buffer_->unregisterConsumer(consumerID);
544 //
545 // __CFG_COUT__ << "Un-Registered consumer '" << consumerID <<
546 // "' from buffer '" << bufferID << ".'" << __E__;
547 // {__CFG_SS__; dumpStatus((std::ostream*)&ss); __CFG_COUT__ << ss.str() << __E__;}
586 //
602 //
603 // __CFG_SS__ << "While Un-Registering, consumer '" << consumerID <<
604 // "' not found!" << __E__;
605 // __CFG_SS_THROW__;
606 //} //end unregisterConsumer()
607 //
609 // void DataManager::unregisterProducer(const std::string& bufferID, const std::string&
610 // producerID)
611 //{
612 // __CFG_COUT__ << "Un-Registering producer '" << producerID <<
613 // "' from buffer '" << bufferID << "'..." << __E__;
614 //
615 // auto bufferIt = buffers_.find(bufferID);
616 // if(bufferIt == buffers_.end())
617 // {
618 // __CFG_SS__ << "While Un-Registering producer '" << producerID <<
619 // ",' buffer '" << bufferID << "' not found!" << __E__;
620 // __CFG_SS_THROW__;
621 // }
622 //
623 // //DO NOT DO ANY STRING BASED UNREGISTERING.. leave it to end of DataManager halt
624 // //bufferIt->second.unregisterProducer(producerID);
625 //
626 // __CFG_COUT__ << "Un-Registered producer '" << producerID <<
627 // "' from buffer '" << bufferID << ".'" << __E__;
628 // {__CFG_SS__; dumpStatus((std::ostream*)&ss); __CFG_COUT__ << ss.str() << __E__;}
629 //} //end unregisterProducer()
630 
631 //========================================================================================================================
632 void DataManager::unregisterFEProducer(const std::string& bufferID,
633  const std::string& feProducerID)
634 {
635  __CFG_COUT__ << "Un-Registering FE-producer '" << feProducerID << "' from buffer '"
636  << bufferID << "'..." << __E__;
637 
638  auto bufferIt = buffers_.find(bufferID);
639  if(bufferIt == buffers_.end())
640  {
641  __CFG_SS__ << "While Un-Registering FE-producer '" << feProducerID
642  << ",' buffer '" << bufferID << "' not found!" << __E__;
643  __CFG_SS_THROW__;
644  }
645 
646  // DO NOT DO ANY STRING BASED UNREGISTERING.. leave it to end of DataManager halt
647  // DO NOT DO bufferIt->second.unregisterProducer(producerID);
648 
649  // remove from producer vector
650  // just destroy consumer, and it unregisters itself
651  for(auto feProducerIt = bufferIt->second.producers_.begin();
652  feProducerIt != bufferIt->second.producers_.end();
653  feProducerIt++)
654  {
655  if((*feProducerIt)->getProcessorID() == feProducerID)
656  {
657  // do not delete pointer before erasing
658  // because FEVInterfacesManager will delete FEProducer instance
659  bufferIt->second.producers_.erase(feProducerIt);
660  break;
661  }
662  }
663 
664  __CFG_COUT__ << "Un-Registered FE-producer '" << feProducerID << "' from buffer '"
665  << bufferID << ".'" << __E__;
666  {
667  __CFG_SS__;
668  dumpStatus((std::ostream*)&ss);
669  __CFG_COUT__ << ss.str() << __E__;
670  }
671 
672 } // end unregisterFEProducer()
673 
674 //========================================================================================================================
675 // registerProducer
676 // DataManager takes ownership of producer pointer
677 // and is now responsible for destructing.
678 // Note: in the future, we could pass a shared_ptr, so that source of pointer could
679 // share in destructing responsibility.
680 void DataManager::registerProducer(const std::string& bufferUID,
681  DataProducerBase* producer)
682 {
683  __CFG_COUT__ << "Registering producer '" << producer->getProcessorID()
684  << "' to buffer '" << bufferUID << "'..." << __E__;
685 
686  auto bufferIt = buffers_.find(bufferUID);
687  if(bufferIt == buffers_.end())
688  {
689  __CFG_SS__ << "Can't find buffer UID '" + bufferUID << "' for producer '"
690  << producer->getProcessorID()
691  << ".' Make sure that your configuration is correct!" << __E__;
692 
693  ss << "\n\n Here is the list of buffers:" << __E__;
694  for(const auto bufferPair : buffers_)
695  ss << bufferPair.first << __E__;
696  ss << "\n\n";
697 
698  __CFG_SS_THROW__;
699  }
700 
701  {
702  __CFG_SS__ << "Before!" << __E__;
703  dumpStatus((std::ostream*)&ss);
704  __CFG_COUT__ << ss.str() << __E__;
705  }
706 
707  __CFG_COUTV__(producer->getBufferSize());
708  bufferIt->second.buffer_->registerProducer(producer, producer->getBufferSize());
709  bufferIt->second.producers_.push_back(producer); // this is where ownership is taken!
710 
711  {
712  __CFG_SS__ << "After!" << __E__;
713  dumpStatus((std::ostream*)&ss);
714  __CFG_COUT__ << ss.str() << __E__;
715  }
716 }
717 
718 //========================================================================================================================
719 void DataManager::registerConsumer(const std::string& bufferUID, DataConsumer* consumer)
720 {
721  __CFG_COUT__ << "Registering consumer '" << consumer->getProcessorID()
722  << "' to buffer '" << bufferUID << "'..." << __E__;
723 
724  auto bufferIt = buffers_.find(bufferUID);
725  if(bufferIt == buffers_.end())
726  {
727  __CFG_SS__ << "Can't find buffer UID '" + bufferUID << "' for consumer '"
728  << consumer->getProcessorID()
729  << ".' Make sure that your configuration is correct!" << __E__;
730 
731  ss << "\n\n Here is the list of buffers:" << __E__;
732  for(const auto bufferPair : buffers_)
733  ss << bufferPair.first << __E__;
734 
735  __CFG_SS_THROW__;
736  }
737 
738  {
739  __CFG_SS__ << "Before!" << __E__;
740  dumpStatus((std::ostream*)&ss);
741  __CFG_COUT__ << ss.str() << __E__;
742  }
743 
744  bufferIt->second.buffer_->registerConsumer(consumer);
745  bufferIt->second.consumers_.push_back(consumer); // this is where ownership is taken!
746 
747  {
748  __CFG_SS__ << "After!" << __E__;
749  dumpStatus((std::ostream*)&ss);
750  __CFG_COUT__ << ss.str() << __E__;
751  }
752 }
753 
754 //========================================================================================================================
755 void DataManager::startAllBuffers(const std::string& runNumber)
756 {
757  for(auto it = buffers_.begin(); it != buffers_.end(); it++)
758  startBuffer(it->first, runNumber);
759 }
760 
761 //========================================================================================================================
762 void DataManager::stopAllBuffers(void)
763 {
764  for(auto it = buffers_.begin(); it != buffers_.end(); it++)
765  stopBuffer(it->first);
766 }
767 
768 //========================================================================================================================
769 void DataManager::resumeAllBuffers(void)
770 {
771  for(auto it = buffers_.begin(); it != buffers_.end(); it++)
772  resumeBuffer(it->first);
773 }
774 
775 //========================================================================================================================
776 void DataManager::pauseAllBuffers(void)
777 {
778  for(auto it = buffers_.begin(); it != buffers_.end(); it++)
779  pauseBuffer(it->first);
780 }
781 
782 //========================================================================================================================
783 void DataManager::startBuffer(const std::string& bufferUID, std::string runNumber)
784 {
785  __CFG_COUT__ << "Starting... " << bufferUID << __E__;
786 
787  buffers_[bufferUID].buffer_->reset();
788  for(auto& it : buffers_[bufferUID].consumers_)
789  {
790  // use try..catch to make sure there is some identifying trail for errors
791  try
792  {
793  it->startProcessingData(runNumber);
794  }
795  catch(...)
796  {
797  __CFG_COUT_WARN__ << "An error occurred while starting consumer '"
798  << it->getProcessorID() << "'..." << __E__;
799  throw;
800  }
801  }
802 
803  for(auto& it : buffers_[bufferUID].producers_)
804  {
805  // use try..catch to make sure there is some identifying trail for errors
806  try
807  {
808  it->startProcessingData(runNumber);
809  }
810  catch(...)
811  {
812  __CFG_COUT_WARN__ << "An error occurred while starting producer '"
813  << it->getProcessorID() << "'..." << __E__;
814  throw;
815  }
816  }
817 
818  buffers_[bufferUID].status_ = Running;
819 
820 } // end startBuffer()
821 
822 //========================================================================================================================
823 void DataManager::stopBuffer(const std::string& bufferUID)
824 {
825  __CFG_COUT__ << "Stopping... " << bufferUID << __E__;
826 
827  __CFG_COUT__ << "Stopping producers..." << __E__;
828  for(auto& it : buffers_[bufferUID].producers_)
829  {
830  // use try..catch to make sure there is some identifying trail for errors
831  try
832  {
833  it->stopProcessingData();
834  }
835  catch(...)
836  {
837  __CFG_COUT_WARN__ << "An error occurred while stopping producer '"
838  << it->getProcessorID() << "'..." << __E__;
839  throw;
840  }
841  }
842 
843  // Wait until all buffers are flushed
844  unsigned int timeOut = 0;
845  const unsigned int ratio = 100;
846  const unsigned int sleepTime = 1000 * ratio;
847  unsigned int totalSleepTime =
848  sleepTime / ratio *
849  buffers_[bufferUID]
850  .buffer_->getTotalNumberOfSubBuffers(); // 1 milliseconds for each buffer!!!!
851  if(totalSleepTime < 5000000)
852  totalSleepTime = 5000000; // At least 5 seconds
853  while(!buffers_[bufferUID].buffer_->isEmpty())
854  {
855  usleep(sleepTime);
856  timeOut += sleepTime;
857  if(timeOut > totalSleepTime)
858  {
859  __CFG_COUT__ << "Couldn't flush all buffers! Timing out after "
860  << totalSleepTime / 1000000. << " seconds!" << __E__;
861  buffers_[bufferUID].buffer_->isEmpty();
862  break;
863  }
864  }
865  __CFG_COUT__ << "Stopping consumers, buffer MUST BE EMPTY. Is buffer empty? "
866  << (buffers_[bufferUID].buffer_->isEmpty() ? "yes" : "no") << __E__;
867 
868  for(auto& it : buffers_[bufferUID].consumers_)
869  {
870  // use try..catch to make sure there is some identifying trail for errors
871  try
872  {
873  it->stopProcessingData();
874  }
875  catch(...)
876  {
877  __CFG_COUT_WARN__ << "An error occurred while stopping consumer '"
878  << it->getProcessorID() << "'..." << __E__;
879  throw;
880  }
881  }
882 
883  buffers_[bufferUID].buffer_->reset();
884  buffers_[bufferUID].status_ = Initialized;
885 } // end stopBuffer()
886 
887 //========================================================================================================================
888 void DataManager::resumeBuffer(const std::string& bufferUID)
889 {
890  __CFG_COUT__ << "Resuming... " << bufferUID << __E__;
891 
892  for(auto& it : buffers_[bufferUID].consumers_)
893  it->resumeProcessingData();
894  for(auto& it : buffers_[bufferUID].producers_)
895  it->resumeProcessingData();
896 
897  buffers_[bufferUID].status_ = Running;
898 } // end resumeBuffer()
899 
900 //========================================================================================================================
901 void DataManager::pauseBuffer(const std::string& bufferUID)
902 {
903  __CFG_COUT__ << "Pausing... " << bufferUID << __E__;
904 
905  for(auto& it : buffers_[bufferUID].producers_)
906  it->pauseProcessingData();
907  // Wait until all buffers are flushed
908  unsigned int timeOut = 0;
909  const unsigned int sleepTime = 1000;
910  while(!buffers_[bufferUID].buffer_->isEmpty())
911  {
912  usleep(sleepTime);
913  timeOut += sleepTime;
914  if(timeOut >
915  sleepTime *
916  buffers_[bufferUID].buffer_->getTotalNumberOfSubBuffers()) // 1
917  // milliseconds
918  // for each
919  // buffer!!!!
920  {
921  __CFG_COUT__ << "Couldn't flush all buffers! Timing out after "
922  << buffers_[bufferUID].buffer_->getTotalNumberOfSubBuffers() *
923  sleepTime / 1000000.
924  << " seconds!" << __E__;
925  break;
926  }
927  }
928  for(auto& it : buffers_[bufferUID].consumers_)
929  it->pauseProcessingData();
930  buffers_[bufferUID].status_ = Initialized;
931 } // end pauseBuffer()
void unregisterFEProducer(const std::string &bufferID, const std::string &feProducerID)
Definition: DataManager.cc:632
void startAllBuffers(const std::string &runNumber)
Definition: DataManager.cc:755