1 #include "otsdaq-core/DataManager/DataManager.h"
2 #include "otsdaq-core/DataManager/CircularBuffer.h"
3 #include "otsdaq-core/DataManager/DataProducer.h"
4 #include "otsdaq-core/DataManager/DataConsumer.h"
5 #include "otsdaq-core/MessageFacility/MessageFacility.h"
6 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
7 #include "otsdaq-core/PluginMakers/MakeDataProcessor.h"
8 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
33 DataManager::DataManager(
const ConfigurationTree& theXDAQContextConfigTree,
const std::string& supervisorConfigurationPath)
34 :
Configurable(theXDAQContextConfigTree, supervisorConfigurationPath)
38 DataManager::~DataManager(
void)
44 void DataManager::configure(
void)
48 for(
const auto& buffer: theXDAQContextConfigTree_.getNode(theConfigurationPath_+
"/LinkToDataManagerConfiguration").getChildren())
50 __MOUT__ <<
"Data Buffer Name: "<< buffer.first << std::endl;
51 if(buffer.second.getNode(
"Status").getValue<
bool>())
53 std::vector<unsigned int> producersVectorLocation;
54 std::vector<unsigned int> consumersVectorLocation;
55 auto bufferConfigurationList = buffer.second.getNode(
"LinkToDataBufferConfiguration").getChildren();
56 unsigned int location = 0;
57 for(
const auto& bufferConfiguration: bufferConfigurationList)
59 __MOUT__ <<
"Processor id: " << bufferConfiguration.first << std::endl;
60 if(bufferConfiguration.second.getNode(
"Status").getValue<
bool>())
62 if(bufferConfiguration.second.getNode(
"ProcessorType").getValue<std::string>() ==
"Producer")
64 producersVectorLocation.push_back(location);
66 else if(bufferConfiguration.second.getNode(
"ProcessorType").getValue<std::string>() ==
"Consumer")
68 consumersVectorLocation.push_back(location);
72 __SS__ <<
"Node ProcessorType in "
73 << bufferConfiguration.first
75 << bufferConfiguration.second.getNode(
"ProcessorType").getValue<std::string>()
76 <<
" is invalid. The only accepted types are Producer and Consumer" << std::endl;
77 throw std::runtime_error(ss.str());
83 if(producersVectorLocation.size() == 0 || consumersVectorLocation.size() == 0)
85 __SS__ <<
"Node Data Buffer "
87 <<
" has " << producersVectorLocation.size() <<
" Producers"
88 <<
" and " << consumersVectorLocation.size() <<
" Consumers"
89 <<
" there must be at least 1 of both configured for the buffer!" << std::endl;
90 throw std::runtime_error(ss.str());
94 configureBuffer<std::string,std::map<std::string,std::string>>(buffer.first);
95 for(
auto& producerLocation: producersVectorLocation)
99 __MOUT__ << bufferConfigurationList[producerLocation].first << std::endl;
104 buffers_[buffer.first].producers_.push_back( std::shared_ptr<DataProducer>(dynamic_cast<DataProducer*>(
107 bufferConfigurationList[producerLocation].second.getNode(
"ProcessorPluginName").getValue<std::string>()
108 , theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode(
"ApplicationUID").getValue<std::string>()
110 , bufferConfigurationList[producerLocation].first
111 , theXDAQContextConfigTree_
112 , theConfigurationPath_ +
"/LinkToDataManagerConfiguration/" + buffer.first +
"/LinkToDataBufferConfiguration/" + bufferConfigurationList[producerLocation].first +
"/LinkToProcessorConfiguration"
114 __MOUT__ << bufferConfigurationList[producerLocation].first <<
" has been created!" << std::endl;
116 for(
auto& consumerLocation: consumersVectorLocation)
120 __MOUT__ << bufferConfigurationList[consumerLocation].first << std::endl;
126 buffers_[buffer.first].consumers_.push_back( std::shared_ptr<DataConsumer>(dynamic_cast<DataConsumer*>(
129 bufferConfigurationList[consumerLocation].second.getNode(
"ProcessorPluginName").getValue<std::string>()
130 , theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode(
"ApplicationUID").getValue<std::string>()
132 , bufferConfigurationList[consumerLocation].first
133 , theXDAQContextConfigTree_
134 , theConfigurationPath_ +
"/LinkToDataManagerConfiguration/" + buffer.first +
"/LinkToDataBufferConfiguration/" + bufferConfigurationList[consumerLocation].first +
"/LinkToProcessorConfiguration"
136 __MOUT__ << bufferConfigurationList[consumerLocation].first <<
" has been created!" << std::endl;
216 void DataManager::halt(
void)
219 DataManager::eraseAllBuffers();
223 void DataManager::pause(
void)
225 DataManager::pauseAllBuffers();
229 void DataManager::resume(
void)
231 DataManager::resumeAllBuffers();
234 void DataManager::start(std::string runNumber)
240 void DataManager::stop()
242 DataManager::stopAllBuffers();
246 void DataManager::eraseAllBuffers(
void)
248 for(
auto& it: buffers_)
249 deleteBuffer(it.first);
257 if(deleteBuffer(bufferUID))
258 buffers_.erase(bufferUID);
262 bool DataManager::unregisterConsumer(std::string consumerID)
264 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
265 for(
auto& itc: it->second.consumers_)
267 if(itc->getProcessorID() == consumerID)
269 it->second.buffer_->unregisterConsumer(itc.get());
278 bool DataManager::deleteBuffer(std::string bufferUID)
280 auto it = buffers_.find(bufferUID);
281 if(it != buffers_.end())
283 auto aBuffer = it->second;
284 if(aBuffer.status_ == Running)
285 stopBuffer(bufferUID);
287 for(
auto& itc: aBuffer.consumers_)
289 aBuffer.buffer_->unregisterConsumer(itc.get());
292 aBuffer.consumers_.clear();
295 aBuffer.producers_.clear();
297 delete aBuffer.buffer_;
304 void DataManager::registerProducer(std::string bufferUID,
DataProducer* producer)
306 buffers_[bufferUID].buffer_->registerProducer(producer, producer->getBufferSize());
310 void DataManager::registerConsumer(std::string bufferUID,
DataConsumer* consumer,
bool registerToBuffer)
313 if(buffers_.find(bufferUID) == buffers_.end())
314 throw std::runtime_error(
"Can't find buffer UID: " + bufferUID +
". Make sure that your configuration is correct!");
315 buffers_[bufferUID].buffer_->registerConsumer(consumer);
327 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
328 startBuffer(it->first, runNumber);
332 void DataManager::stopAllBuffers (
void)
334 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
335 stopBuffer(it->first);
339 void DataManager::resumeAllBuffers(
void)
341 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
342 resumeBuffer(it->first);
346 void DataManager::pauseAllBuffers (
void)
348 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
349 pauseBuffer(it->first);
353 void DataManager::startBuffer(std::string bufferUID, std::string runNumber)
355 buffers_[bufferUID].buffer_->reset();
356 for(
auto& it: buffers_[bufferUID].consumers_)
357 it->startProcessingData(runNumber);
358 for(
auto& it: buffers_[bufferUID].producers_)
359 it->startProcessingData(runNumber);
360 buffers_[bufferUID].status_ = Running;
364 void DataManager::stopBuffer(std::string bufferUID)
366 for(
auto& it: buffers_[bufferUID].producers_)
367 it->stopProcessingData();
370 unsigned int timeOut = 0;
371 const unsigned int ratio = 100;
372 const unsigned int sleepTime = 1000*ratio;
373 unsigned int totalSleepTime = sleepTime/ratio*buffers_[bufferUID].buffer_->getNumberOfBuffers();
374 if(totalSleepTime < 5000000)
375 totalSleepTime = 5000000;
376 while(!buffers_[bufferUID].buffer_->isEmpty())
379 timeOut += sleepTime;
380 if(timeOut > totalSleepTime)
382 std::cout <<
"Couldn't flush all buffers! Timing out after " << totalSleepTime/1000000. <<
" seconds!" << std::endl;
383 buffers_[bufferUID].buffer_->isEmpty();
387 std::cout <<
"Stopping consumers, buffer MUST BE EMPTY. Is buffer empty? "<< buffers_[bufferUID].buffer_->isEmpty() << std::endl;
388 for(
auto& it: buffers_[bufferUID].consumers_)
389 it->stopProcessingData();
390 buffers_[bufferUID].buffer_->reset();
391 buffers_[bufferUID].status_ = Initialized;
395 void DataManager::resumeBuffer(std::string bufferUID)
397 for(
auto& it: buffers_[bufferUID].consumers_)
398 it->resumeProcessingData();
399 for(
auto& it: buffers_[bufferUID].producers_)
400 it->resumeProcessingData();
401 buffers_[bufferUID].status_ = Running;
405 void DataManager::pauseBuffer(std::string bufferUID)
407 for(
auto& it: buffers_[bufferUID].producers_)
408 it->pauseProcessingData();
410 unsigned int timeOut = 0;
411 const unsigned int sleepTime = 1000;
412 while(!buffers_[bufferUID].buffer_->isEmpty())
415 timeOut += sleepTime;
416 if(timeOut > sleepTime*buffers_[bufferUID].buffer_->getNumberOfBuffers())
418 std::cout <<
"Couldn't flush all buffers! Timing out after " << buffers_[bufferUID].buffer_->getNumberOfBuffers()*sleepTime/1000000. <<
" seconds!" << std::endl;
422 for(
auto& it: buffers_[bufferUID].consumers_)
423 it->pauseProcessingData();
424 buffers_[bufferUID].status_ = Initialized;
void eraseBuffer(std::string bufferUID)
!!!!Delete all Buffers and all the pointers of the producers and consumers
void startAllBuffers(std::string runNumber)
!!!!Delete all the pointers of the producers and consumers