$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/DataManager/DataManager.h" 00002 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h" 00003 #include "otsdaq-core/DataManager/CircularBuffer.h" 00004 #include "otsdaq-core/DataManager/DataConsumer.h" 00005 #include "otsdaq-core/DataManager/DataProducerBase.h" 00006 #include "otsdaq-core/Macros/CoutMacros.h" 00007 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00008 #include "otsdaq-core/PluginMakers/MakeDataProcessor.h" 00009 00010 /* 00011 #include "otsdaq-core/TablePluginDataFormats/ARTDAQConsumerTable.h" 00012 #include "otsdaq-core/TablePluginDataFormats/DataBufferTable.h" 00013 #include "otsdaq-core/TablePluginDataFormats/DataManagerTable.h" 00014 #include 00015 "otsdaq-core/TablePluginDataFormats/UDPDataListenerProducerTable.h" 00016 #include "otsdaq-core/DataProcessorPlugins/ARTDAQConsumer.h" 00017 #include "otsdaq-core/DataProcessorPlugins/DQMHistosConsumer.h" 00018 #include "otsdaq-core/DataProcessorPlugins/DataListenerProducer.h" 00019 #include "otsdaq-core/DataProcessorPlugins/DataStreamer.h" 00020 #include "otsdaq-core/DataProcessorPlugins/RawDataSaverConsumer.h" 00021 #include "otsdaq-core/EventBuilder/AssociativeMemoryEventBuilder.h" 00022 #include "otsdaq-core/EventBuilder/Event.h" 00023 #include "otsdaq-core/EventBuilder/EventDataSaver.h" 00024 */ 00025 00026 #include <unistd.h> //usleep 00027 #include <iostream> 00028 #include <vector> 00029 00030 using namespace ots; 00031 00032 //======================================================================================================================== 00033 DataManager::DataManager(const ConfigurationTree& theXDAQContextConfigTree, 00034 const std::string& supervisorConfigurationPath) 00035 : Configurable(theXDAQContextConfigTree, supervisorConfigurationPath) 00036 , parentSupervisorHasFrontends_(false) 00037 { 00038 __CFG_COUT__ << "Constructed." << __E__; 00039 } // end constructor 00040 00041 //======================================================================================================================== 00042 DataManager::~DataManager(void) 00043 { 00044 __CFG_COUT__ << "Destructor." << __E__; 00045 DataManager::destroyBuffers(); 00046 __CFG_COUT__ << "Destructed." << __E__; 00047 } // end destructor 00048 00049 //======================================================================================================================== 00050 void DataManager::dumpStatus(std::ostream* out) const 00051 { 00052 *out << "Buffer count: " << buffers_.size() << __E__; 00053 for(auto& bufferPair : buffers_) 00054 { 00055 *out << "\t" 00056 << "Buffer '" << bufferPair.first << "' status=" << bufferPair.second.status_ 00057 << " producers=" << bufferPair.second.producers_.size() 00058 << " consumers=" << bufferPair.second.consumers_.size() << __E__; 00059 00060 *out << "\t\t" 00061 << "Producers:" << __E__; 00062 for(auto& producer : bufferPair.second.producers_) 00063 { 00064 *out << "\t\t\t" << producer->getProcessorID() << " [" 00065 << bufferPair.second.buffer_->getProducerBufferSize( 00066 producer->getProcessorID()) 00067 << "]" << __E__; 00068 } 00069 *out << "\t\t" 00070 << "Consumers:" << __E__; 00071 for(auto& consumer : bufferPair.second.consumers_) 00072 { 00073 *out << "\t\t\t" << consumer->getProcessorID() << __E__; 00074 } 00075 } 00076 } // end dumpStatus() 00077 00078 //======================================================================================================================== 00079 void DataManager::configure(void) 00080 { 00081 const std::string transitionName = "Configuring"; 00082 00083 const std::string COL_NAME_bufferGroupLink = "LinkToDataBufferTable"; 00084 const std::string COL_NAME_processorGroupLink = "LinkToDataProcessorTable"; 00085 const std::string COL_NAME_processorType = "ProcessorType"; 00086 const std::string COL_NAME_processorPlugin = "ProcessorPluginName"; 00087 const std::string COL_NAME_processorLink = "LinkToProcessorTable"; 00088 const std::string COL_NAME_appUID = "ApplicationUID"; 00089 00090 __CFG_COUT__ << transitionName << " DataManager" << __E__; 00091 __CFG_COUT__ << "Path: " << theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink 00092 << __E__; 00093 00094 destroyBuffers(); 00095 00096 // get all buffer definitions from configuration tree 00097 for(const auto& buffer : 00098 theXDAQContextConfigTree_ 00099 .getNode(theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink) 00100 .getChildren()) //"/LinkToDataManagerTable").getChildren()) 00101 { 00102 __CFG_COUT__ << "Data Buffer Name: " << buffer.first << __E__; 00103 if(buffer.second.getNode(TableViewColumnInfo::COL_NAME_STATUS).getValue<bool>()) 00104 { 00105 std::vector<unsigned int> producersVectorLocation; 00106 std::vector<unsigned int> consumersVectorLocation; 00107 auto bufferConfigurationList = 00108 buffer.second.getNode(COL_NAME_processorGroupLink) 00109 .getChildren(); //"LinkToDataBufferTable").getChildren(); 00110 unsigned int location = 0; 00111 for(const auto& bufferConfiguration : bufferConfigurationList) 00112 { 00113 __CFG_COUT__ << "Processor id: " << bufferConfiguration.first << __E__; 00114 if(bufferConfiguration.second 00115 .getNode(TableViewColumnInfo::COL_NAME_STATUS) 00116 .getValue<bool>()) 00117 { 00118 if(bufferConfiguration.second.getNode(COL_NAME_processorType) 00119 .getValue<std::string>() == "Producer") 00120 { 00121 producersVectorLocation.push_back(location); 00122 } 00123 else if(bufferConfiguration.second.getNode(COL_NAME_processorType) 00124 .getValue<std::string>() == "Consumer") 00125 { 00126 consumersVectorLocation.push_back(location); 00127 } 00128 else 00129 { 00130 __CFG_SS__ << "Node ProcessorType in " 00131 << bufferConfiguration.first << " of type " 00132 << bufferConfiguration.second 00133 .getNode(COL_NAME_processorPlugin) 00134 .getValue<std::string>() 00135 << " is invalid. The only accepted types are Producer " 00136 "and Consumer" 00137 << __E__; 00138 __CFG_MOUT_ERR__ << ss.str(); 00139 __CFG_SS_THROW__; 00140 } 00141 } 00142 ++location; 00143 00144 } // end loop sorting by producer and consumer 00145 00146 if(!parentSupervisorHasFrontends_ && 00147 producersVectorLocation.size() == 00148 0) // || consumersVectorLocation.size() == 0) 00149 { 00150 __CFG_SS__ << "Node Data Buffer " << buffer.first << " has " 00151 << producersVectorLocation.size() << " Producers" 00152 << " and " << consumersVectorLocation.size() << " Consumers" 00153 << " there must be at least 1 Producer " 00154 << // of both configured 00155 "for the buffer!" << __E__; 00156 __CFG_MOUT_ERR__ << ss.str(); 00157 __CFG_SS_THROW__; 00158 } 00159 00160 if(parentSupervisorHasFrontends_) 00161 __CFG_COUT__ 00162 << "Parent supervisor has front-ends, so FE-producers may " 00163 << "be instantiated in the configure steps of the FESupervisor." 00164 << __E__; 00165 00166 configureBuffer<std::string, std::map<std::string, std::string> >( 00167 buffer.first); 00168 00169 for(auto& producerLocation : producersVectorLocation) 00170 { 00171 // __CFG_COUT__ << theConfigurationPath_ << __E__; 00172 // __CFG_COUT__ << buffer.first << __E__; 00173 __CFG_COUT__ << "Creating producer... " 00174 << bufferConfigurationList[producerLocation].first << __E__; 00175 // __CFG_COUT__ << 00176 // bufferConfigurationMap[producer].getNode(COL_NAME_processorPlugin).getValue<std::string>() 00177 //<< __E__; 00178 // __CFG_COUT__ << 00179 // bufferConfigurationMap[producer].getNode("LinkToProcessorTable") << 00180 // __E__; 00181 // __CFG_COUT__ << "THIS DATA MANAGER POINTER: " << this << 00182 // __E__; 00183 // __CFG_COUT__ << "PASSED" << __E__; 00184 00185 try 00186 { 00187 // buffers_[buffer.first].producers_.push_back(std::shared_ptr<DataProducerBase>( 00188 DataProducerBase* tmpCastCheck = 00189 dynamic_cast<DataProducerBase*>(makeDataProcessor( 00190 bufferConfigurationList[producerLocation] 00191 .second.getNode(COL_NAME_processorPlugin) 00192 .getValue<std::string>(), 00193 theXDAQContextConfigTree_.getBackNode(theConfigurationPath_) 00194 .getNode(COL_NAME_appUID) 00195 .getValue<std::string>(), 00196 buffer.first, 00197 bufferConfigurationList[producerLocation].first, 00198 theXDAQContextConfigTree_, 00199 theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink + "/" + 00200 buffer.first + "/" + COL_NAME_processorGroupLink + "/" + 00201 bufferConfigurationList[producerLocation].first + "/" + 00202 COL_NAME_processorLink)); //)); 00203 00204 if(!tmpCastCheck) 00205 { 00206 __CFG_SS__ << "Construction failed for producer '" 00207 << bufferConfigurationList[producerLocation].first 00208 << "!' Null pointer returned." << __E__; 00209 __CFG_SS_THROW__; 00210 } 00211 __CFG_COUT__ << tmpCastCheck->getProcessorID() << __E__; 00212 00213 { 00214 __CFG_SS__; 00215 dumpStatus((std::ostream*)&ss); 00216 __CFG_COUT__ << ss.str() << __E__; 00217 } 00218 } 00219 catch(const std::bad_cast& e) 00220 { 00221 __CFG_SS__ << "Failed to instantiate producer plugin named '" 00222 << bufferConfigurationList[producerLocation].first 00223 << "' of type '" 00224 << bufferConfigurationList[producerLocation] 00225 .second.getNode(COL_NAME_processorPlugin) 00226 .getValue<std::string>() 00227 << "' due to the following error: \n" 00228 << e.what() << __E__; 00229 __CFG_MOUT_ERR__ << ss.str(); 00230 __CFG_SS_THROW__; 00231 } 00232 catch(const cet::exception& e) 00233 { 00234 __CFG_SS__ << "Failed to instantiate producer plugin named '" 00235 << bufferConfigurationList[producerLocation].first 00236 << "' of type '" 00237 << bufferConfigurationList[producerLocation] 00238 .second.getNode(COL_NAME_processorPlugin) 00239 .getValue<std::string>() 00240 << "' due to the following error: \n" 00241 << e.what() << __E__; 00242 __CFG_MOUT_ERR__ << ss.str(); 00243 __CFG_SS_THROW__; 00244 } 00245 catch(const std::runtime_error& e) 00246 { 00247 __CFG_SS__ << "Failed to instantiate producer plugin named '" 00248 << bufferConfigurationList[producerLocation].first 00249 << "' of type '" 00250 << bufferConfigurationList[producerLocation] 00251 .second.getNode(COL_NAME_processorPlugin) 00252 .getValue<std::string>() 00253 << "' due to the following error: \n" 00254 << e.what() << __E__; 00255 __CFG_MOUT_ERR__ << ss.str(); 00256 __CFG_SS_THROW__; 00257 } 00258 catch(...) 00259 { 00260 __CFG_SS__ << "Failed to instantiate producer plugin named '" 00261 << bufferConfigurationList[producerLocation].first 00262 << "' of type '" 00263 << bufferConfigurationList[producerLocation] 00264 .second.getNode(COL_NAME_processorPlugin) 00265 .getValue<std::string>() 00266 << "' due to an unknown error." << __E__; 00267 __CFG_MOUT_ERR__ << ss.str(); 00268 throw; // if we do not throw, it is hard to tell what is causing the 00269 // problem.. 00270 //__CFG_SS_THROW__; 00271 } 00272 __CFG_COUT__ << bufferConfigurationList[producerLocation].first 00273 << " has been created!" << __E__; 00274 } // end producer creation loop 00275 00276 for(auto& consumerLocation : consumersVectorLocation) 00277 { 00278 // __CFG_COUT__ << theConfigurationPath_ << __E__; 00279 // __CFG_COUT__ << buffer.first << __E__; 00280 __CFG_COUT__ << "Creating consumer... " 00281 << bufferConfigurationList[consumerLocation].first << __E__; 00282 // __CFG_COUT__ << 00283 // bufferConfigurationMap[consumer].getNode(COL_NAME_processorPlugin).getValue<std::string>() 00284 //<< __E__; 00285 // __CFG_COUT__ << 00286 // bufferConfigurationMap[consumer].getNode("LinkToProcessorTable") << 00287 // __E__; 00288 // __CFG_COUT__ << 00289 // theXDAQContextConfigTree_.getBackNode(theConfigurationPath_) << 00290 // __E__; 00291 // __CFG_COUT__ << "THIS DATA MANAGER POINTER: " << this << 00292 // __E__; 00293 // __CFG_COUT__ << "PASSED" << __E__; 00294 try 00295 { 00296 // buffers_[buffer.first].consumers_.push_back(std::shared_ptr<DataConsumer>( 00297 DataConsumer* tmpCastCheck = 00298 dynamic_cast<DataConsumer*>(makeDataProcessor( 00299 bufferConfigurationList[consumerLocation] 00300 .second.getNode(COL_NAME_processorPlugin) 00301 .getValue<std::string>(), 00302 theXDAQContextConfigTree_.getBackNode(theConfigurationPath_) 00303 .getNode(COL_NAME_appUID) 00304 .getValue<std::string>(), 00305 buffer.first, 00306 bufferConfigurationList[consumerLocation].first, 00307 theXDAQContextConfigTree_, 00308 theConfigurationPath_ + "/" + COL_NAME_bufferGroupLink + "/" + 00309 buffer.first + "/" + COL_NAME_processorGroupLink + "/" + 00310 bufferConfigurationList[consumerLocation].first + "/" + 00311 COL_NAME_processorLink)); //)); 00312 00313 if(!tmpCastCheck) 00314 { 00315 __CFG_SS__ << "Construction failed for consumer '" 00316 << bufferConfigurationList[consumerLocation].first 00317 << "!' Null pointer returned." << __E__; 00318 __CFG_SS_THROW__; 00319 } 00320 00321 { 00322 __CFG_SS__; 00323 dumpStatus((std::ostream*)&ss); 00324 __CFG_COUT__ << ss.str() << __E__; 00325 } 00326 } 00327 catch(const std::bad_cast& e) 00328 { 00329 __CFG_SS__ << "Failed to instantiate consumer plugin named '" 00330 << bufferConfigurationList[consumerLocation].first 00331 << "' of type '" 00332 << bufferConfigurationList[consumerLocation] 00333 .second.getNode(COL_NAME_processorPlugin) 00334 .getValue<std::string>() 00335 << "' due to the following error: \n" 00336 << e.what() << __E__; 00337 __CFG_MOUT_ERR__ << ss.str(); 00338 __CFG_SS_THROW__; 00339 } 00340 catch(const cet::exception& e) 00341 { 00342 __CFG_SS__ << "Failed to instantiate consumer plugin named '" 00343 << bufferConfigurationList[consumerLocation].first 00344 << "' of type '" 00345 << bufferConfigurationList[consumerLocation] 00346 .second.getNode(COL_NAME_processorPlugin) 00347 .getValue<std::string>() 00348 << "' due to the following error: \n" 00349 << e.what() << __E__; 00350 __CFG_MOUT_ERR__ << ss.str(); 00351 __CFG_SS_THROW__; 00352 } 00353 catch(const std::runtime_error& e) 00354 { 00355 __CFG_SS__ << "Failed to instantiate consumer plugin named '" 00356 << bufferConfigurationList[consumerLocation].first 00357 << "' of type '" 00358 << bufferConfigurationList[consumerLocation] 00359 .second.getNode(COL_NAME_processorPlugin) 00360 .getValue<std::string>() 00361 << "' due to the following error: \n" 00362 << e.what() << __E__; 00363 __CFG_MOUT_ERR__ << ss.str(); 00364 __CFG_SS_THROW__; 00365 } 00366 catch(...) 00367 { 00368 __CFG_SS__ << "Failed to instantiate consumer plugin named '" 00369 << bufferConfigurationList[consumerLocation].first 00370 << "' of type '" 00371 << bufferConfigurationList[consumerLocation] 00372 .second.getNode(COL_NAME_processorPlugin) 00373 .getValue<std::string>() 00374 << "' due to an unknown error." << __E__; 00375 __CFG_MOUT_ERR__ << ss.str(); 00376 throw; // if we do not throw, it is hard to tell what is happening.. 00377 //__CFG_SS_THROW__; 00378 } 00379 __CFG_COUT__ << bufferConfigurationList[consumerLocation].first 00380 << " has been created!" << __E__; 00381 } // end consumer creation loop 00382 } 00383 } 00384 } // end configure() 00385 00386 //======================================================================================================================== 00387 void DataManager::halt(void) 00388 { 00389 const std::string transitionName = "Halting"; 00390 00391 __CFG_COUT__ << transitionName << " DataManager " << __E__; 00392 00393 // since halting also occurs on errors, ignore more errors 00394 try 00395 { 00396 stop(); 00397 } 00398 catch(...) 00399 { 00400 __CFG_COUT_WARN__ << "An error occurred while halting the Data Manager, ignoring." 00401 << __E__; 00402 } 00403 00404 stop(); 00405 00406 __CFG_COUT__ << transitionName << " DataManager stopped. Now destruct buffers..." 00407 << __E__; 00408 00409 DataManager::destroyBuffers(); // Stop all Buffers, deletes all pointers, and delete 00410 // Buffer struct 00411 } // end halt() 00412 00413 //======================================================================================================================== 00414 void DataManager::pause(void) 00415 { 00416 const std::string transitionName = "Pausing"; 00417 00418 __CFG_COUT__ << transitionName << " DataManager " << __E__; 00419 00420 DataManager::pauseAllBuffers(); 00421 } // end pause() 00422 00423 //======================================================================================================================== 00424 void DataManager::resume(void) 00425 { 00426 const std::string transitionName = "Resuming"; 00427 00428 __CFG_COUT__ << transitionName << " DataManager " << __E__; 00429 00430 DataManager::resumeAllBuffers(); 00431 } // end resume() 00432 00433 //======================================================================================================================== 00434 void DataManager::start(std::string runNumber) 00435 { 00436 const std::string transitionName = "Starting"; 00437 00438 __CFG_COUT__ << transitionName << " DataManager " << __E__; 00439 00440 DataManager::startAllBuffers(runNumber); 00441 } // end start() 00442 00443 //======================================================================================================================== 00444 void DataManager::stop() 00445 { 00446 const std::string transitionName = "Stopping"; 00447 00448 __CFG_COUT__ << transitionName << " DataManager " << __E__; 00449 00450 DataManager::stopAllBuffers(); 00451 } // end stop() 00452 00453 //======================================================================================================================== 00454 // destroyBuffers 00455 // Stop all Buffers, deletes all pointers, and delete Buffer struct 00456 void DataManager::destroyBuffers(void) 00457 { 00458 DataManager::stopAllBuffers(); 00459 00460 for(auto& bufferPair : buffers_) 00461 { 00462 // delete all producers/consumers 00463 // then delete CircularBuffer 00464 for(auto& producer : bufferPair.second.producers_) 00465 delete producer; 00466 bufferPair.second.producers_.clear(); 00467 00468 for(auto& consumer : bufferPair.second.consumers_) 00469 delete consumer; 00470 bufferPair.second.consumers_.clear(); 00471 00472 delete bufferPair.second.buffer_; 00473 } // end delete buffer loop 00474 00475 buffers_.clear(); 00476 } // end destroyBuffers() 00477 00479 // void DataManager::eraseBuffer(const std::string& bufferUID) 00480 //{ 00481 // if (deleteBuffer(bufferUID)) 00482 // buffers_.erase(bufferUID); 00483 //} //end eraseBuffer() 00484 // 00486 // 00487 // bool DataManager::deleteBuffer(const std::string& bufferUID) 00488 //{ 00489 // auto it = buffers_.find(bufferUID); 00490 // if (it != buffers_.end()) 00491 // { 00492 // auto aBuffer = it->second; 00493 // if (aBuffer.status_ == Running) 00494 // stopBuffer(bufferUID); 00495 // 00501 // aBuffer.consumers_.clear(); 00502 // // for(auto& itp: aBuffer.producers_) 00503 // // delete itp; 00504 // aBuffer.producers_.clear(); 00505 // 00506 // delete aBuffer.buffer_; 00507 // return true; 00508 // } 00509 // return false; 00510 //} //end deleteBuffer() 00511 // 00518 // void DataManager::unregisterConsumer(const std::string& bufferID, const std::string& 00519 // consumerID) 00520 //{ 00521 // __CFG_COUT__ << "Un-Registering consumer '" << consumerID << 00522 // "' from buffer '" << bufferID << "'..." << __E__; 00523 // 00524 // auto bufferIt = buffers_.find(bufferID); 00525 // if(bufferIt == buffers_.end()) 00526 // { 00527 // __CFG_SS__ << "While Un-Registering consumer '" << consumerID << 00528 // ",' buffer '" << bufferID << "' not found!" << __E__; 00529 // __CFG_SS_THROW__; 00530 // } 00531 // 00532 // //just destroy consumer, and it unregisters itself 00533 // for (auto consumerIt = bufferIt->second.consumers_.begin(); 00534 // consumerIt != bufferIt->second.consumers_.end(); consumerIt++) 00535 // { 00536 // if((*consumerIt)->getProcessorID() == consumerID) 00537 // { 00538 // bufferIt->second.consumers_.erase(consumerIt); 00539 // break; 00540 // } 00541 // } 00542 // //DO NOT DO ANY STRING BASED UNREGISTERING.. leave it to end of DataManager halt 00543 // //bufferIt->second.buffer_->unregisterConsumer(consumerID); 00544 // 00545 // __CFG_COUT__ << "Un-Registered consumer '" << consumerID << 00546 // "' from buffer '" << bufferID << ".'" << __E__; 00547 // {__CFG_SS__; dumpStatus((std::ostream*)&ss); __CFG_COUT__ << ss.str() << __E__;} 00586 // 00602 // 00603 // __CFG_SS__ << "While Un-Registering, consumer '" << consumerID << 00604 // "' not found!" << __E__; 00605 // __CFG_SS_THROW__; 00606 //} //end unregisterConsumer() 00607 // 00609 // void DataManager::unregisterProducer(const std::string& bufferID, const std::string& 00610 // producerID) 00611 //{ 00612 // __CFG_COUT__ << "Un-Registering producer '" << producerID << 00613 // "' from buffer '" << bufferID << "'..." << __E__; 00614 // 00615 // auto bufferIt = buffers_.find(bufferID); 00616 // if(bufferIt == buffers_.end()) 00617 // { 00618 // __CFG_SS__ << "While Un-Registering producer '" << producerID << 00619 // ",' buffer '" << bufferID << "' not found!" << __E__; 00620 // __CFG_SS_THROW__; 00621 // } 00622 // 00623 // //DO NOT DO ANY STRING BASED UNREGISTERING.. leave it to end of DataManager halt 00624 // //bufferIt->second.unregisterProducer(producerID); 00625 // 00626 // __CFG_COUT__ << "Un-Registered producer '" << producerID << 00627 // "' from buffer '" << bufferID << ".'" << __E__; 00628 // {__CFG_SS__; dumpStatus((std::ostream*)&ss); __CFG_COUT__ << ss.str() << __E__;} 00629 //} //end unregisterProducer() 00630 00631 //======================================================================================================================== 00632 void DataManager::unregisterFEProducer(const std::string& bufferID, 00633 const std::string& feProducerID) 00634 { 00635 __CFG_COUT__ << "Un-Registering FE-producer '" << feProducerID << "' from buffer '" 00636 << bufferID << "'..." << __E__; 00637 00638 auto bufferIt = buffers_.find(bufferID); 00639 if(bufferIt == buffers_.end()) 00640 { 00641 __CFG_SS__ << "While Un-Registering FE-producer '" << feProducerID 00642 << ",' buffer '" << bufferID << "' not found!" << __E__; 00643 __CFG_SS_THROW__; 00644 } 00645 00646 // DO NOT DO ANY STRING BASED UNREGISTERING.. leave it to end of DataManager halt 00647 // DO NOT DO bufferIt->second.unregisterProducer(producerID); 00648 00649 // remove from producer vector 00650 // just destroy consumer, and it unregisters itself 00651 for(auto feProducerIt = bufferIt->second.producers_.begin(); 00652 feProducerIt != bufferIt->second.producers_.end(); 00653 feProducerIt++) 00654 { 00655 if((*feProducerIt)->getProcessorID() == feProducerID) 00656 { 00657 // do not delete pointer before erasing 00658 // because FEVInterfacesManager will delete FEProducer instance 00659 bufferIt->second.producers_.erase(feProducerIt); 00660 break; 00661 } 00662 } 00663 00664 __CFG_COUT__ << "Un-Registered FE-producer '" << feProducerID << "' from buffer '" 00665 << bufferID << ".'" << __E__; 00666 { 00667 __CFG_SS__; 00668 dumpStatus((std::ostream*)&ss); 00669 __CFG_COUT__ << ss.str() << __E__; 00670 } 00671 00672 } // end unregisterFEProducer() 00673 00674 //======================================================================================================================== 00675 // registerProducer 00676 // DataManager takes ownership of producer pointer 00677 // and is now responsible for destructing. 00678 // Note: in the future, we could pass a shared_ptr, so that source of pointer could 00679 // share in destructing responsibility. 00680 void DataManager::registerProducer(const std::string& bufferUID, 00681 DataProducerBase* producer) 00682 { 00683 __CFG_COUT__ << "Registering producer '" << producer->getProcessorID() 00684 << "' to buffer '" << bufferUID << "'..." << __E__; 00685 00686 auto bufferIt = buffers_.find(bufferUID); 00687 if(bufferIt == buffers_.end()) 00688 { 00689 __CFG_SS__ << "Can't find buffer UID '" + bufferUID << "' for producer '" 00690 << producer->getProcessorID() 00691 << ".' Make sure that your configuration is correct!" << __E__; 00692 00693 ss << "\n\n Here is the list of buffers:" << __E__; 00694 for(const auto bufferPair : buffers_) 00695 ss << bufferPair.first << __E__; 00696 ss << "\n\n"; 00697 00698 __CFG_SS_THROW__; 00699 } 00700 00701 { 00702 __CFG_SS__ << "Before!" << __E__; 00703 dumpStatus((std::ostream*)&ss); 00704 __CFG_COUT__ << ss.str() << __E__; 00705 } 00706 00707 __CFG_COUTV__(producer->getBufferSize()); 00708 bufferIt->second.buffer_->registerProducer(producer, producer->getBufferSize()); 00709 bufferIt->second.producers_.push_back(producer); // this is where ownership is taken! 00710 00711 { 00712 __CFG_SS__ << "After!" << __E__; 00713 dumpStatus((std::ostream*)&ss); 00714 __CFG_COUT__ << ss.str() << __E__; 00715 } 00716 } 00717 00718 //======================================================================================================================== 00719 void DataManager::registerConsumer(const std::string& bufferUID, DataConsumer* consumer) 00720 { 00721 __CFG_COUT__ << "Registering consumer '" << consumer->getProcessorID() 00722 << "' to buffer '" << bufferUID << "'..." << __E__; 00723 00724 auto bufferIt = buffers_.find(bufferUID); 00725 if(bufferIt == buffers_.end()) 00726 { 00727 __CFG_SS__ << "Can't find buffer UID '" + bufferUID << "' for consumer '" 00728 << consumer->getProcessorID() 00729 << ".' Make sure that your configuration is correct!" << __E__; 00730 00731 ss << "\n\n Here is the list of buffers:" << __E__; 00732 for(const auto bufferPair : buffers_) 00733 ss << bufferPair.first << __E__; 00734 00735 __CFG_SS_THROW__; 00736 } 00737 00738 { 00739 __CFG_SS__ << "Before!" << __E__; 00740 dumpStatus((std::ostream*)&ss); 00741 __CFG_COUT__ << ss.str() << __E__; 00742 } 00743 00744 bufferIt->second.buffer_->registerConsumer(consumer); 00745 bufferIt->second.consumers_.push_back(consumer); // this is where ownership is taken! 00746 00747 { 00748 __CFG_SS__ << "After!" << __E__; 00749 dumpStatus((std::ostream*)&ss); 00750 __CFG_COUT__ << ss.str() << __E__; 00751 } 00752 } 00753 00754 //======================================================================================================================== 00755 void DataManager::startAllBuffers(const std::string& runNumber) 00756 { 00757 for(auto it = buffers_.begin(); it != buffers_.end(); it++) 00758 startBuffer(it->first, runNumber); 00759 } 00760 00761 //======================================================================================================================== 00762 void DataManager::stopAllBuffers(void) 00763 { 00764 for(auto it = buffers_.begin(); it != buffers_.end(); it++) 00765 stopBuffer(it->first); 00766 } 00767 00768 //======================================================================================================================== 00769 void DataManager::resumeAllBuffers(void) 00770 { 00771 for(auto it = buffers_.begin(); it != buffers_.end(); it++) 00772 resumeBuffer(it->first); 00773 } 00774 00775 //======================================================================================================================== 00776 void DataManager::pauseAllBuffers(void) 00777 { 00778 for(auto it = buffers_.begin(); it != buffers_.end(); it++) 00779 pauseBuffer(it->first); 00780 } 00781 00782 //======================================================================================================================== 00783 void DataManager::startBuffer(const std::string& bufferUID, std::string runNumber) 00784 { 00785 __CFG_COUT__ << "Starting... " << bufferUID << __E__; 00786 00787 buffers_[bufferUID].buffer_->reset(); 00788 for(auto& it : buffers_[bufferUID].consumers_) 00789 { 00790 // use try..catch to make sure there is some identifying trail for errors 00791 try 00792 { 00793 it->startProcessingData(runNumber); 00794 } 00795 catch(...) 00796 { 00797 __CFG_COUT_WARN__ << "An error occurred while starting consumer '" 00798 << it->getProcessorID() << "'..." << __E__; 00799 throw; 00800 } 00801 } 00802 00803 for(auto& it : buffers_[bufferUID].producers_) 00804 { 00805 // use try..catch to make sure there is some identifying trail for errors 00806 try 00807 { 00808 it->startProcessingData(runNumber); 00809 } 00810 catch(...) 00811 { 00812 __CFG_COUT_WARN__ << "An error occurred while starting producer '" 00813 << it->getProcessorID() << "'..." << __E__; 00814 throw; 00815 } 00816 } 00817 00818 buffers_[bufferUID].status_ = Running; 00819 00820 } // end startBuffer() 00821 00822 //======================================================================================================================== 00823 void DataManager::stopBuffer(const std::string& bufferUID) 00824 { 00825 __CFG_COUT__ << "Stopping... " << bufferUID << __E__; 00826 00827 __CFG_COUT__ << "Stopping producers..." << __E__; 00828 for(auto& it : buffers_[bufferUID].producers_) 00829 { 00830 // use try..catch to make sure there is some identifying trail for errors 00831 try 00832 { 00833 it->stopProcessingData(); 00834 } 00835 catch(...) 00836 { 00837 __CFG_COUT_WARN__ << "An error occurred while stopping producer '" 00838 << it->getProcessorID() << "'..." << __E__; 00839 throw; 00840 } 00841 } 00842 00843 // Wait until all buffers are flushed 00844 unsigned int timeOut = 0; 00845 const unsigned int ratio = 100; 00846 const unsigned int sleepTime = 1000 * ratio; 00847 unsigned int totalSleepTime = 00848 sleepTime / ratio * 00849 buffers_[bufferUID] 00850 .buffer_->getTotalNumberOfSubBuffers(); // 1 milliseconds for each buffer!!!! 00851 if(totalSleepTime < 5000000) 00852 totalSleepTime = 5000000; // At least 5 seconds 00853 while(!buffers_[bufferUID].buffer_->isEmpty()) 00854 { 00855 usleep(sleepTime); 00856 timeOut += sleepTime; 00857 if(timeOut > totalSleepTime) 00858 { 00859 __CFG_COUT__ << "Couldn't flush all buffers! Timing out after " 00860 << totalSleepTime / 1000000. << " seconds!" << __E__; 00861 buffers_[bufferUID].buffer_->isEmpty(); 00862 break; 00863 } 00864 } 00865 __CFG_COUT__ << "Stopping consumers, buffer MUST BE EMPTY. Is buffer empty? " 00866 << (buffers_[bufferUID].buffer_->isEmpty() ? "yes" : "no") << __E__; 00867 00868 for(auto& it : buffers_[bufferUID].consumers_) 00869 { 00870 // use try..catch to make sure there is some identifying trail for errors 00871 try 00872 { 00873 it->stopProcessingData(); 00874 } 00875 catch(...) 00876 { 00877 __CFG_COUT_WARN__ << "An error occurred while stopping consumer '" 00878 << it->getProcessorID() << "'..." << __E__; 00879 throw; 00880 } 00881 } 00882 00883 buffers_[bufferUID].buffer_->reset(); 00884 buffers_[bufferUID].status_ = Initialized; 00885 } // end stopBuffer() 00886 00887 //======================================================================================================================== 00888 void DataManager::resumeBuffer(const std::string& bufferUID) 00889 { 00890 __CFG_COUT__ << "Resuming... " << bufferUID << __E__; 00891 00892 for(auto& it : buffers_[bufferUID].consumers_) 00893 it->resumeProcessingData(); 00894 for(auto& it : buffers_[bufferUID].producers_) 00895 it->resumeProcessingData(); 00896 00897 buffers_[bufferUID].status_ = Running; 00898 } // end resumeBuffer() 00899 00900 //======================================================================================================================== 00901 void DataManager::pauseBuffer(const std::string& bufferUID) 00902 { 00903 __CFG_COUT__ << "Pausing... " << bufferUID << __E__; 00904 00905 for(auto& it : buffers_[bufferUID].producers_) 00906 it->pauseProcessingData(); 00907 // Wait until all buffers are flushed 00908 unsigned int timeOut = 0; 00909 const unsigned int sleepTime = 1000; 00910 while(!buffers_[bufferUID].buffer_->isEmpty()) 00911 { 00912 usleep(sleepTime); 00913 timeOut += sleepTime; 00914 if(timeOut > 00915 sleepTime * 00916 buffers_[bufferUID].buffer_->getTotalNumberOfSubBuffers()) // 1 00917 // milliseconds 00918 // for each 00919 // buffer!!!! 00920 { 00921 __CFG_COUT__ << "Couldn't flush all buffers! Timing out after " 00922 << buffers_[bufferUID].buffer_->getTotalNumberOfSubBuffers() * 00923 sleepTime / 1000000. 00924 << " seconds!" << __E__; 00925 break; 00926 } 00927 } 00928 for(auto& it : buffers_[bufferUID].consumers_) 00929 it->pauseProcessingData(); 00930 buffers_[bufferUID].status_ = Initialized; 00931 } // end pauseBuffer()