00001 #include "otsdaq-core/DataManager/DataManager.h"
00002 #include "otsdaq-core/DataManager/CircularBuffer.h"
00003 #include "otsdaq-core/DataManager/DataProducer.h"
00004 #include "otsdaq-core/DataManager/DataConsumer.h"
00005 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00006 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00007 #include "otsdaq-core/PluginMakers/MakeDataProcessor.h"
00008 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <iostream>
00027 #include <vector>
00028 #include <unistd.h>
00029
00030 using namespace ots;
00031
00032
00033 DataManager::DataManager(const ConfigurationTree& theXDAQContextConfigTree, const std::string& supervisorConfigurationPath)
00034 : Configurable(theXDAQContextConfigTree, supervisorConfigurationPath)
00035 {}
00036
00037
00038 DataManager::~DataManager(void)
00039 {
00040 eraseAllBuffers();
00041 }
00042
00043
00044 void DataManager::configure(void)
00045 {
00046 eraseAllBuffers();
00047
00048 for(const auto& buffer: theXDAQContextConfigTree_.getNode(theConfigurationPath_+"/LinkToDataManagerConfiguration").getChildren())
00049 {
00050 __MOUT__ << "Data Buffer Name: "<< buffer.first << std::endl;
00051 if(buffer.second.getNode("Status").getValue<bool>())
00052 {
00053 std::vector<unsigned int> producersVectorLocation;
00054 std::vector<unsigned int> consumersVectorLocation;
00055 auto bufferConfigurationList = buffer.second.getNode("LinkToDataBufferConfiguration").getChildren();
00056 unsigned int location = 0;
00057 for(const auto& bufferConfiguration: bufferConfigurationList)
00058 {
00059 __MOUT__ << "Processor id: " << bufferConfiguration.first << std::endl;
00060 if(bufferConfiguration.second.getNode("Status").getValue<bool>())
00061 {
00062 if(bufferConfiguration.second.getNode("ProcessorType").getValue<std::string>() == "Producer")
00063 {
00064 producersVectorLocation.push_back(location);
00065 }
00066 else if(bufferConfiguration.second.getNode("ProcessorType").getValue<std::string>() == "Consumer")
00067 {
00068 consumersVectorLocation.push_back(location);
00069 }
00070 else
00071 {
00072 __SS__ << "Node ProcessorType in "
00073 << bufferConfiguration.first
00074 << " of type "
00075 << bufferConfiguration.second.getNode("ProcessorType").getValue<std::string>()
00076 << " is invalid. The only accepted types are Producer and Consumer" << std::endl;
00077 throw std::runtime_error(ss.str());
00078 }
00079 }
00080 ++location;
00081
00082 }
00083 if(producersVectorLocation.size() == 0 || consumersVectorLocation.size() == 0)
00084 {
00085 __SS__ << "Node Data Buffer "
00086 << buffer.first
00087 << " has " << producersVectorLocation.size() << " Producers"
00088 << " and " << consumersVectorLocation.size() << " Consumers"
00089 << " there must be at least 1 of both configured for the buffer!" << std::endl;
00090 throw std::runtime_error(ss.str());
00091
00092 }
00093
00094 configureBuffer<std::string,std::map<std::string,std::string>>(buffer.first);
00095 for(auto& producerLocation: producersVectorLocation)
00096 {
00097
00098
00099 __MOUT__ << bufferConfigurationList[producerLocation].first << std::endl;
00100
00101
00102
00103
00104 buffers_[buffer.first].producers_.push_back( std::shared_ptr<DataProducer>(dynamic_cast<DataProducer*>(
00105 makeDataProcessor
00106 (
00107 bufferConfigurationList[producerLocation].second.getNode("ProcessorPluginName").getValue<std::string>()
00108 , theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode("ApplicationUID").getValue<std::string>()
00109 , buffer.first
00110 , bufferConfigurationList[producerLocation].first
00111 , theXDAQContextConfigTree_
00112 , theConfigurationPath_ + "/LinkToDataManagerConfiguration/" + buffer.first + "/LinkToDataBufferConfiguration/" + bufferConfigurationList[producerLocation].first + "/LinkToProcessorConfiguration"
00113 ))));
00114 __MOUT__ << bufferConfigurationList[producerLocation].first << " has been created!" << std::endl;
00115 }
00116 for(auto& consumerLocation: consumersVectorLocation)
00117 {
00118
00119
00120 __MOUT__ << bufferConfigurationList[consumerLocation].first << std::endl;
00121
00122
00123
00124
00125
00126 buffers_[buffer.first].consumers_.push_back( std::shared_ptr<DataConsumer>(dynamic_cast<DataConsumer*>(
00127 makeDataProcessor
00128 (
00129 bufferConfigurationList[consumerLocation].second.getNode("ProcessorPluginName").getValue<std::string>()
00130 , theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode("ApplicationUID").getValue<std::string>()
00131 , buffer.first
00132 , bufferConfigurationList[consumerLocation].first
00133 , theXDAQContextConfigTree_
00134 , theConfigurationPath_ + "/LinkToDataManagerConfiguration/" + buffer.first + "/LinkToDataBufferConfiguration/" + bufferConfigurationList[consumerLocation].first + "/LinkToProcessorConfiguration"
00135 ))));
00136 __MOUT__ << bufferConfigurationList[consumerLocation].first << " has been created!" << std::endl;
00137 }
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 }
00214
00215
00216 void DataManager::halt(void)
00217 {
00218 stop();
00219 DataManager::eraseAllBuffers();
00220 }
00221
00222
00223 void DataManager::pause(void)
00224 {
00225 DataManager::pauseAllBuffers();
00226 }
00227
00228
00229 void DataManager::resume(void)
00230 {
00231 DataManager::resumeAllBuffers();
00232 }
00233
00234 void DataManager::start(std::string runNumber)
00235 {
00236 DataManager::startAllBuffers(runNumber);
00237 }
00238
00239
00240 void DataManager::stop()
00241 {
00242 DataManager::stopAllBuffers();
00243 }
00244
00245
00246 void DataManager::eraseAllBuffers(void)
00247 {
00248 for(auto& it: buffers_)
00249 deleteBuffer(it.first);
00250
00251 buffers_.clear();
00252 }
00253
00254
00255 void DataManager::eraseBuffer(std::string bufferUID)
00256 {
00257 if(deleteBuffer(bufferUID))
00258 buffers_.erase(bufferUID);
00259 }
00260
00261
00262 bool DataManager::unregisterConsumer(std::string consumerID)
00263 {
00264 for(auto it=buffers_.begin(); it!=buffers_.end(); it++)
00265 for(auto& itc: it->second.consumers_)
00266 {
00267 if(itc->getProcessorID() == consumerID)
00268 {
00269 it->second.buffer_->unregisterConsumer(itc.get());
00270 return true;
00271 }
00272 }
00273
00274 return false;
00275 }
00276
00277
00278 bool DataManager::deleteBuffer(std::string bufferUID)
00279 {
00280 auto it = buffers_.find(bufferUID);
00281 if(it != buffers_.end())
00282 {
00283 auto aBuffer = it->second;
00284 if(aBuffer.status_ == Running)
00285 stopBuffer(bufferUID);
00286
00287 for(auto& itc: aBuffer.consumers_)
00288 {
00289 aBuffer.buffer_->unregisterConsumer(itc.get());
00290
00291 }
00292 aBuffer.consumers_.clear();
00293
00294
00295 aBuffer.producers_.clear();
00296
00297 delete aBuffer.buffer_;
00298 return true;
00299 }
00300 return false;
00301 }
00302
00303
00304 void DataManager::registerProducer(std::string bufferUID, DataProducer* producer)
00305 {
00306 buffers_[bufferUID].buffer_->registerProducer(producer, producer->getBufferSize());
00307 }
00308
00309
00310 void DataManager::registerConsumer(std::string bufferUID, DataConsumer* consumer, bool registerToBuffer)
00311 {
00312 if(registerToBuffer)
00313 if(buffers_.find(bufferUID) == buffers_.end())
00314 throw std::runtime_error("Can't find buffer UID: " + bufferUID + ". Make sure that your configuration is correct!");
00315 buffers_[bufferUID].buffer_->registerConsumer(consumer);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 void DataManager::startAllBuffers(std::string runNumber)
00326 {
00327 for(auto it=buffers_.begin(); it!=buffers_.end(); it++)
00328 startBuffer(it->first, runNumber);
00329 }
00330
00331
00332 void DataManager::stopAllBuffers (void)
00333 {
00334 for(auto it=buffers_.begin(); it!=buffers_.end(); it++)
00335 stopBuffer(it->first);
00336 }
00337
00338
00339 void DataManager::resumeAllBuffers(void)
00340 {
00341 for(auto it=buffers_.begin(); it!=buffers_.end(); it++)
00342 resumeBuffer(it->first);
00343 }
00344
00345
00346 void DataManager::pauseAllBuffers (void)
00347 {
00348 for(auto it=buffers_.begin(); it!=buffers_.end(); it++)
00349 pauseBuffer(it->first);
00350 }
00351
00352
00353 void DataManager::startBuffer(std::string bufferUID, std::string runNumber)
00354 {
00355 buffers_[bufferUID].buffer_->reset();
00356 for(auto& it: buffers_[bufferUID].consumers_)
00357 it->startProcessingData(runNumber);
00358 for(auto& it: buffers_[bufferUID].producers_)
00359 it->startProcessingData(runNumber);
00360 buffers_[bufferUID].status_ = Running;
00361 }
00362
00363
00364 void DataManager::stopBuffer(std::string bufferUID)
00365 {
00366 for(auto& it: buffers_[bufferUID].producers_)
00367 it->stopProcessingData();
00368
00369
00370 unsigned int timeOut = 0;
00371 const unsigned int ratio = 100;
00372 const unsigned int sleepTime = 1000*ratio;
00373 unsigned int totalSleepTime = sleepTime/ratio*buffers_[bufferUID].buffer_->getNumberOfBuffers();
00374 if(totalSleepTime < 5000000)
00375 totalSleepTime = 5000000;
00376 while(!buffers_[bufferUID].buffer_->isEmpty())
00377 {
00378 usleep(sleepTime);
00379 timeOut += sleepTime;
00380 if(timeOut > totalSleepTime)
00381 {
00382 std::cout << "Couldn't flush all buffers! Timing out after " << totalSleepTime/1000000. << " seconds!" << std::endl;
00383 buffers_[bufferUID].buffer_->isEmpty();
00384 break;
00385 }
00386 }
00387 std::cout << "Stopping consumers, buffer MUST BE EMPTY. Is buffer empty? "<< buffers_[bufferUID].buffer_->isEmpty() << std::endl;
00388 for(auto& it: buffers_[bufferUID].consumers_)
00389 it->stopProcessingData();
00390 buffers_[bufferUID].buffer_->reset();
00391 buffers_[bufferUID].status_ = Initialized;
00392 }
00393
00394
00395 void DataManager::resumeBuffer(std::string bufferUID)
00396 {
00397 for(auto& it: buffers_[bufferUID].consumers_)
00398 it->resumeProcessingData();
00399 for(auto& it: buffers_[bufferUID].producers_)
00400 it->resumeProcessingData();
00401 buffers_[bufferUID].status_ = Running;
00402 }
00403
00404
00405 void DataManager::pauseBuffer(std::string bufferUID)
00406 {
00407 for(auto& it: buffers_[bufferUID].producers_)
00408 it->pauseProcessingData();
00409
00410 unsigned int timeOut = 0;
00411 const unsigned int sleepTime = 1000;
00412 while(!buffers_[bufferUID].buffer_->isEmpty())
00413 {
00414 usleep(sleepTime);
00415 timeOut += sleepTime;
00416 if(timeOut > sleepTime*buffers_[bufferUID].buffer_->getNumberOfBuffers())
00417 {
00418 std::cout << "Couldn't flush all buffers! Timing out after " << buffers_[bufferUID].buffer_->getNumberOfBuffers()*sleepTime/1000000. << " seconds!" << std::endl;
00419 break;
00420 }
00421 }
00422 for(auto& it: buffers_[bufferUID].consumers_)
00423 it->pauseProcessingData();
00424 buffers_[bufferUID].status_ = Initialized;
00425 }