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 __COUT__ <<
"Data Buffer Name: " << buffer.first << std::endl;
51 if (buffer.second.getNode(ViewColumnInfo::COL_NAME_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 __COUT__ <<
"Processor id: " << bufferConfiguration.first << std::endl;
60 if (bufferConfiguration.second.getNode(ViewColumnInfo::COL_NAME_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 __COUT__ << 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 __COUT__ << bufferConfigurationList[producerLocation].first <<
" has been created!" << std::endl;
118 for (
auto& consumerLocation : consumersVectorLocation)
122 __COUT__ << 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 __COUT__ << bufferConfigurationList[consumerLocation].first <<
" has been created!" << std::endl;
218 void DataManager::halt(
void)
221 DataManager::eraseAllBuffers();
225 void DataManager::pause(
void)
227 __COUT__ <<
"Pausing..." << std::endl;
228 DataManager::pauseAllBuffers();
232 void DataManager::resume(
void)
234 DataManager::resumeAllBuffers();
237 void DataManager::start(std::string runNumber)
243 void DataManager::stop()
245 DataManager::stopAllBuffers();
249 void DataManager::eraseAllBuffers(
void)
251 for (
auto& it : buffers_)
252 deleteBuffer(it.first);
260 if (deleteBuffer(bufferUID))
261 buffers_.erase(bufferUID);
265 bool DataManager::unregisterConsumer(std::string consumerID)
267 for (
auto it = buffers_.begin(); it != buffers_.end(); it++)
268 for (
auto& itc : it->second.consumers_)
270 if (itc->getProcessorID() == consumerID)
272 it->second.buffer_->unregisterConsumer(itc.get());
281 bool DataManager::deleteBuffer(std::string bufferUID)
283 auto it = buffers_.find(bufferUID);
284 if (it != buffers_.end())
286 auto aBuffer = it->second;
287 if (aBuffer.status_ == Running)
288 stopBuffer(bufferUID);
290 for (
auto& itc : aBuffer.consumers_)
292 aBuffer.buffer_->unregisterConsumer(itc.get());
295 aBuffer.consumers_.clear();
298 aBuffer.producers_.clear();
300 delete aBuffer.buffer_;
307 void DataManager::registerProducer(std::string bufferUID,
DataProducer* producer)
309 buffers_[bufferUID].buffer_->registerProducer(producer, producer->getBufferSize());
313 void DataManager::registerConsumer(std::string bufferUID,
DataConsumer* consumer,
bool registerToBuffer)
315 if (registerToBuffer)
317 if (buffers_.find(bufferUID) == buffers_.end())
319 __SS__ << (
"Can't find buffer UID: " + bufferUID +
". Make sure that your configuration is correct!") << std::endl;
320 __COUT_ERR__ << ss.str();
321 throw std::runtime_error(ss.str());
323 buffers_[bufferUID].buffer_->registerConsumer(consumer);
336 for (
auto it = buffers_.begin(); it != buffers_.end(); it++)
337 startBuffer(it->first, runNumber);
341 void DataManager::stopAllBuffers(
void)
343 for (
auto it = buffers_.begin(); it != buffers_.end(); it++)
344 stopBuffer(it->first);
348 void DataManager::resumeAllBuffers(
void)
350 for (
auto it = buffers_.begin(); it != buffers_.end(); it++)
351 resumeBuffer(it->first);
355 void DataManager::pauseAllBuffers(
void)
357 for (
auto it = buffers_.begin(); it != buffers_.end(); it++)
358 pauseBuffer(it->first);
362 void DataManager::startBuffer(std::string bufferUID, std::string runNumber)
364 buffers_[bufferUID].buffer_->reset();
365 for (
auto& it : buffers_[bufferUID].consumers_)
366 it->startProcessingData(runNumber);
367 for (
auto& it : buffers_[bufferUID].producers_)
368 it->startProcessingData(runNumber);
369 buffers_[bufferUID].status_ = Running;
373 void DataManager::stopBuffer(std::string bufferUID)
375 for (
auto& it : buffers_[bufferUID].producers_)
376 it->stopProcessingData();
379 unsigned int timeOut = 0;
380 const unsigned int ratio = 100;
381 const unsigned int sleepTime = 1000 * ratio;
382 unsigned int totalSleepTime = sleepTime / ratio * buffers_[bufferUID].buffer_->getNumberOfBuffers();
383 if (totalSleepTime < 5000000)
384 totalSleepTime = 5000000;
385 while (!buffers_[bufferUID].buffer_->isEmpty())
388 timeOut += sleepTime;
389 if (timeOut > totalSleepTime)
391 std::cout <<
"Couldn't flush all buffers! Timing out after " << totalSleepTime / 1000000. <<
" seconds!" << std::endl;
392 buffers_[bufferUID].buffer_->isEmpty();
396 std::cout <<
"Stopping consumers, buffer MUST BE EMPTY. Is buffer empty? " << buffers_[bufferUID].buffer_->isEmpty() << std::endl;
397 for (
auto& it : buffers_[bufferUID].consumers_)
398 it->stopProcessingData();
399 buffers_[bufferUID].buffer_->reset();
400 buffers_[bufferUID].status_ = Initialized;
404 void DataManager::resumeBuffer(std::string bufferUID)
406 for (
auto& it : buffers_[bufferUID].consumers_)
407 it->resumeProcessingData();
408 for (
auto& it : buffers_[bufferUID].producers_)
409 it->resumeProcessingData();
410 buffers_[bufferUID].status_ = Running;
414 void DataManager::pauseBuffer(std::string bufferUID)
416 __COUT__ <<
"Pausing..." << std::endl;
418 for (
auto& it : buffers_[bufferUID].producers_)
419 it->pauseProcessingData();
421 unsigned int timeOut = 0;
422 const unsigned int sleepTime = 1000;
423 while (!buffers_[bufferUID].buffer_->isEmpty())
426 timeOut += sleepTime;
427 if (timeOut > sleepTime*buffers_[bufferUID].buffer_->getNumberOfBuffers())
429 std::cout <<
"Couldn't flush all buffers! Timing out after " << buffers_[bufferUID].buffer_->getNumberOfBuffers()*sleepTime / 1000000. <<
" seconds!" << std::endl;
433 for (
auto& it : buffers_[bufferUID].consumers_)
434 it->pauseProcessingData();
435 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