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());
84 if(producersVectorLocation.size() == 0)
86 __SS__ <<
"Node Data Buffer "
88 <<
" has " << producersVectorLocation.size() <<
" Producers"
89 <<
" and " << consumersVectorLocation.size() <<
" Consumers"
90 <<
" there must be at least 1 Producer " <<
91 "for the buffer!" << std::endl;
92 throw std::runtime_error(ss.str());
96 configureBuffer<std::string,std::map<std::string,std::string>>(buffer.first);
97 for(
auto& producerLocation: producersVectorLocation)
101 __MOUT__ << bufferConfigurationList[producerLocation].first << std::endl;
106 buffers_[buffer.first].producers_.push_back( std::shared_ptr<DataProducer>(dynamic_cast<DataProducer*>(
109 bufferConfigurationList[producerLocation].second.getNode(
"ProcessorPluginName").getValue<std::string>()
110 , theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode(
"ApplicationUID").getValue<std::string>()
112 , bufferConfigurationList[producerLocation].first
113 , theXDAQContextConfigTree_
114 , theConfigurationPath_ +
"/LinkToDataManagerConfiguration/" + buffer.first +
"/LinkToDataBufferConfiguration/" + bufferConfigurationList[producerLocation].first +
"/LinkToProcessorConfiguration"
116 __MOUT__ << bufferConfigurationList[producerLocation].first <<
" has been created!" << std::endl;
118 for(
auto& consumerLocation: consumersVectorLocation)
122 __MOUT__ << bufferConfigurationList[consumerLocation].first << std::endl;
128 buffers_[buffer.first].consumers_.push_back( std::shared_ptr<DataConsumer>(dynamic_cast<DataConsumer*>(
131 bufferConfigurationList[consumerLocation].second.getNode(
"ProcessorPluginName").getValue<std::string>()
132 , theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode(
"ApplicationUID").getValue<std::string>()
134 , bufferConfigurationList[consumerLocation].first
135 , theXDAQContextConfigTree_
136 , theConfigurationPath_ +
"/LinkToDataManagerConfiguration/" + buffer.first +
"/LinkToDataBufferConfiguration/" + bufferConfigurationList[consumerLocation].first +
"/LinkToProcessorConfiguration"
138 __MOUT__ << bufferConfigurationList[consumerLocation].first <<
" has been created!" << std::endl;
218 void DataManager::halt(
void)
221 DataManager::eraseAllBuffers();
225 void DataManager::pause(
void)
227 DataManager::pauseAllBuffers();
231 void DataManager::resume(
void)
233 DataManager::resumeAllBuffers();
236 void DataManager::start(std::string runNumber)
242 void DataManager::stop()
244 DataManager::stopAllBuffers();
248 void DataManager::eraseAllBuffers(
void)
250 for(
auto& it: buffers_)
251 deleteBuffer(it.first);
259 if(deleteBuffer(bufferUID))
260 buffers_.erase(bufferUID);
264 bool DataManager::unregisterConsumer(std::string consumerID)
266 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
267 for(
auto& itc: it->second.consumers_)
269 if(itc->getProcessorID() == consumerID)
271 it->second.buffer_->unregisterConsumer(itc.get());
280 bool DataManager::deleteBuffer(std::string bufferUID)
282 auto it = buffers_.find(bufferUID);
283 if(it != buffers_.end())
285 auto aBuffer = it->second;
286 if(aBuffer.status_ == Running)
287 stopBuffer(bufferUID);
289 for(
auto& itc: aBuffer.consumers_)
291 aBuffer.buffer_->unregisterConsumer(itc.get());
294 aBuffer.consumers_.clear();
297 aBuffer.producers_.clear();
299 delete aBuffer.buffer_;
306 void DataManager::registerProducer(std::string bufferUID,
DataProducer* producer)
308 buffers_[bufferUID].buffer_->registerProducer(producer, producer->getBufferSize());
312 void DataManager::registerConsumer(std::string bufferUID,
DataConsumer* consumer,
bool registerToBuffer)
315 if(buffers_.find(bufferUID) == buffers_.end())
316 throw std::runtime_error(
"Can't find buffer UID: " + bufferUID +
". Make sure that your configuration is correct!");
317 buffers_[bufferUID].buffer_->registerConsumer(consumer);
329 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
330 startBuffer(it->first, runNumber);
334 void DataManager::stopAllBuffers (
void)
336 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
337 stopBuffer(it->first);
341 void DataManager::resumeAllBuffers(
void)
343 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
344 resumeBuffer(it->first);
348 void DataManager::pauseAllBuffers (
void)
350 for(
auto it=buffers_.begin(); it!=buffers_.end(); it++)
351 pauseBuffer(it->first);
355 void DataManager::startBuffer(std::string bufferUID, std::string runNumber)
357 buffers_[bufferUID].buffer_->reset();
358 for(
auto& it: buffers_[bufferUID].consumers_)
359 it->startProcessingData(runNumber);
360 for(
auto& it: buffers_[bufferUID].producers_)
361 it->startProcessingData(runNumber);
362 buffers_[bufferUID].status_ = Running;
366 void DataManager::stopBuffer(std::string bufferUID)
368 for(
auto& it: buffers_[bufferUID].producers_)
369 it->stopProcessingData();
372 unsigned int timeOut = 0;
373 const unsigned int ratio = 100;
374 const unsigned int sleepTime = 1000*ratio;
375 unsigned int totalSleepTime = sleepTime/ratio*buffers_[bufferUID].buffer_->getNumberOfBuffers();
376 if(totalSleepTime < 5000000)
377 totalSleepTime = 5000000;
378 while(!buffers_[bufferUID].buffer_->isEmpty())
381 timeOut += sleepTime;
382 if(timeOut > totalSleepTime)
384 std::cout <<
"Couldn't flush all buffers! Timing out after " << totalSleepTime/1000000. <<
" seconds!" << std::endl;
385 buffers_[bufferUID].buffer_->isEmpty();
389 std::cout <<
"Stopping consumers, buffer MUST BE EMPTY. Is buffer empty? "<< buffers_[bufferUID].buffer_->isEmpty() << std::endl;
390 for(
auto& it: buffers_[bufferUID].consumers_)
391 it->stopProcessingData();
392 buffers_[bufferUID].buffer_->reset();
393 buffers_[bufferUID].status_ = Initialized;
397 void DataManager::resumeBuffer(std::string bufferUID)
399 for(
auto& it: buffers_[bufferUID].consumers_)
400 it->resumeProcessingData();
401 for(
auto& it: buffers_[bufferUID].producers_)
402 it->resumeProcessingData();
403 buffers_[bufferUID].status_ = Running;
407 void DataManager::pauseBuffer(std::string bufferUID)
409 for(
auto& it: buffers_[bufferUID].producers_)
410 it->pauseProcessingData();
412 unsigned int timeOut = 0;
413 const unsigned int sleepTime = 1000;
414 while(!buffers_[bufferUID].buffer_->isEmpty())
417 timeOut += sleepTime;
418 if(timeOut > sleepTime*buffers_[bufferUID].buffer_->getNumberOfBuffers())
420 std::cout <<
"Couldn't flush all buffers! Timing out after " << buffers_[bufferUID].buffer_->getNumberOfBuffers()*sleepTime/1000000. <<
" seconds!" << std::endl;
424 for(
auto& it: buffers_[bufferUID].consumers_)
425 it->pauseProcessingData();
426 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