2 #include "artdaq/DAQdata/Globals.hh"
3 #define TRACE_NAME (app_name + "_BoardReaderCore").c_str()
5 #include "artdaq-core/Data/Fragment.hh"
6 #include "artdaq-core/Utilities/ExceptionHandler.hh"
7 #include "artdaq/Application/BoardReaderCore.hh"
8 #include "artdaq/Application/TaskType.hh"
9 #include "artdaq/Generators/makeCommandableFragmentGenerator.hh"
16 #include "canvas/Utilities/Exception.h"
17 #include "cetlib_except/exception.h"
30 std::unique_ptr<artdaq::DataSenderManager> artdaq::BoardReaderCore::sender_ptr_ =
nullptr;
33 : parent_application_(parent_application)
35 , generator_ptr_(nullptr)
36 , run_id_(art::RunID::flushRun())
38 , stop_requested_(false)
39 , pause_requested_(false)
41 TLOG(TLVL_DEBUG + 32) <<
"Constructor";
52 TLOG(TLVL_DEBUG + 32) <<
"Destructor";
53 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request Receiver BEGIN";
54 request_receiver_ptr_.reset(
nullptr);
55 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request Receiver END";
60 TLOG(TLVL_DEBUG + 32) <<
"initialize method called with "
61 <<
"ParameterSet = \"" << pset.to_string() <<
"\".";
64 fhicl::ParameterSet daq_pset;
67 daq_pset = pset.get<fhicl::ParameterSet>(
"daq");
72 <<
"Unable to find the DAQ parameters in the initialization "
73 <<
"ParameterSet: \"" + pset.to_string() +
"\".";
76 fhicl::ParameterSet fr_pset;
79 fr_pset = daq_pset.get<fhicl::ParameterSet>(
"fragment_receiver");
85 <<
"Unable to find the fragment_receiver parameters in the DAQ "
86 <<
"initialization ParameterSet: \"" + daq_pset.to_string() +
"\".";
91 fhicl::ParameterSet metric_pset;
94 metric_pset = daq_pset.get<fhicl::ParameterSet>(
"metrics");
99 if (metric_pset.is_empty())
101 TLOG(TLVL_INFO) <<
"No metric plugins appear to be defined";
105 metricMan->initialize(metric_pset, app_name);
109 ExceptionHandler(ExceptionHandlerRethrow::no,
110 "Error loading metrics in BoardReaderCore::initialize()");
113 if (daq_pset.has_key(
"rank"))
115 if (my_rank >= 0 && daq_pset.get<
int>(
"rank") != my_rank)
117 TLOG(TLVL_WARNING) <<
"BoardReader rank specified at startup is different than rank specified at configure! Using rank received at configure!";
119 my_rank = daq_pset.get<
int>(
"rank");
123 TLOG(TLVL_ERROR) <<
"BoardReader rank not specified at startup or in configuration! Aborting";
124 throw cet::exception(
"RankNotSpecifiedError") <<
"BoardReader rank not specified at startup or in configuration! Aborting";
128 auto frag_gen_name = fr_pset.get<std::string>(
"generator",
"");
129 if (frag_gen_name.length() == 0)
132 <<
"No fragment generator (parameter name = \"generator\") was "
133 <<
"specified in the fragment_receiver ParameterSet. The "
134 <<
"DAQ initialization PSet was \"" << daq_pset.to_string() <<
"\".";
144 std::stringstream exception_string;
145 exception_string <<
"Exception thrown during initialization of fragment generator of type \""
146 << frag_gen_name <<
"\"";
148 ExceptionHandler(ExceptionHandlerRethrow::no, exception_string.str());
150 TLOG(TLVL_DEBUG + 32) <<
"FHiCL parameter set used to initialize the fragment generator which threw an exception: " << fr_pset.to_string();
157 fragment_buffer_ptr_ = std::make_shared<FragmentBuffer>(fr_pset);
161 std::stringstream exception_string;
162 exception_string <<
"Exception thrown during initialization of Fragment Buffer";
164 ExceptionHandler(ExceptionHandlerRethrow::no, exception_string.str());
166 TLOG(TLVL_DEBUG + 32) <<
"FHiCL parameter set used to initialize the fragment buffer which threw an exception: " << fr_pset.to_string();
171 std::shared_ptr<RequestBuffer> request_buffer = std::make_shared<RequestBuffer>(fr_pset.get<artdaq::Fragment::sequence_id_t>(
"request_increment", 1));
175 request_receiver_ptr_.reset(
new RequestReceiver(fr_pset, request_buffer));
176 generator_ptr_->SetRequestBuffer(request_buffer);
177 generator_ptr_->SetFragmentBuffer(fragment_buffer_ptr_);
178 fragment_buffer_ptr_->SetRequestBuffer(request_buffer);
182 ExceptionHandler(ExceptionHandlerRethrow::no,
"Exception thrown during initialization of request receiver");
184 TLOG(TLVL_DEBUG + 32) <<
"FHiCL parameter set used to initialize the request receiver which threw an exception: " << fr_pset.to_string();
188 metricMan->setPrefix(generator_ptr_->metricsReportingInstanceName());
190 rt_priority_ = fr_pset.get<
int>(
"rt_priority", 0);
193 statsHelper_.createCollectors(fr_pset, 100, 30.0, 60.0, FRAGMENTS_PROCESSED_STAT_KEY);
196 skip_seqId_test_ = (fr_pset.get<
bool>(
"skip_seqID_test",
false) || generator_ptr_->fragmentIDs().size() > 1 || fragment_buffer_ptr_->request_mode() != RequestMode::Ignored);
198 verbose_ = fr_pset.get<
bool>(
"verbose",
true);
205 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Starting run " <<
id.run();
206 stop_requested_.store(
false);
207 pause_requested_.store(
false);
211 statsHelper_.resetStatistics();
213 fragment_buffer_ptr_->Reset(
false);
215 metricMan->do_start();
216 generator_ptr_->StartCmd(
id.run(), timeout, timestamp);
219 request_receiver_ptr_->SetRunNumber(static_cast<uint32_t>(
id.run()));
220 request_receiver_ptr_->startRequestReception();
223 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Start transition (Started run) for run " << run_id_.run()
224 <<
", timeout = " << timeout <<
", timestamp = " << timestamp;
230 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Stopping run " << run_id_.run() <<
" after " << fragment_count_ <<
" fragments.";
231 stop_requested_.store(
true);
233 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request reception BEGIN";
234 request_receiver_ptr_->stopRequestReception();
235 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request reception END";
237 TLOG(TLVL_DEBUG + 32) <<
"Stopping CommandableFragmentGenerator BEGIN";
238 generator_ptr_->StopCmd(timeout, timestamp);
239 TLOG(TLVL_DEBUG + 32) <<
"Stopping CommandableFragmentGenerator END";
241 TLOG(TLVL_DEBUG + 32) <<
"Stopping FragmentBuffer";
242 fragment_buffer_ptr_->Stop();
244 TLOG(TLVL_DEBUG + 32) <<
"Stopping DataSenderManager";
247 sender_ptr_->StopSender();
251 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Stop transition for run " << run_id_.run();
257 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Pausing run " << run_id_.run() <<
" after " << fragment_count_ <<
" fragments.";
258 pause_requested_.store(
true);
259 generator_ptr_->PauseCmd(timeout, timestamp);
260 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Pause transition for run " << run_id_.run();
266 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Resuming run " << run_id_.run();
267 pause_requested_.store(
false);
268 metricMan->do_start();
269 generator_ptr_->ResumeCmd(timeout, timestamp);
270 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Resume transition for run " << run_id_.run();
276 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Starting Shutdown transition";
277 generator_ptr_->joinThreads();
278 generator_ptr_.reset(
nullptr);
279 metricMan->shutdown();
280 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed Shutdown transition";
286 TLOG(TLVL_DEBUG + 32) <<
"soft_initialize method called with "
287 <<
"ParameterSet = \"" << pset.to_string()
288 <<
"\". Forwarding to initialize.";
289 return initialize(pset, timeout, timestamp);
294 TLOG(TLVL_DEBUG + 32) <<
"reinitialize method called with "
295 <<
"ParameterSet = \"" << pset.to_string()
296 <<
"\". Forwarding to initalize.";
297 return initialize(pset, timeout, timestamp);
302 if (rt_priority_ > 0)
304 #pragma GCC diagnostic push
305 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
306 sched_param s_param = {};
307 s_param.sched_priority = rt_priority_;
308 if (pthread_setschedparam(pthread_self(), SCHED_RR, &s_param))
309 TLOG(TLVL_WARNING) <<
"setting realtime priority failed";
310 #pragma GCC diagnostic pop
316 if (rt_priority_ > 0)
318 #pragma GCC diagnostic push
319 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
320 sched_param s_param = {};
321 s_param.sched_priority = rt_priority_;
322 int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
326 <<
"Failed to set realtime priority to " << rt_priority_
327 <<
", return code = " << status;
329 #pragma GCC diagnostic pop
332 TLOG(TLVL_DEBUG + 32) <<
"Waiting for first fragment.";
333 artdaq::MonitoredQuantityStats::TIME_POINT_T startTime, after_input, after_buffer;
334 artdaq::FragmentPtrs frags;
336 receiver_thread_active_ =
true;
338 auto wait_start = std::chrono::steady_clock::now();
339 while (!running_ && TimeUtils::GetElapsedTime(wait_start) < start_transition_timeout_)
345 TLOG(TLVL_ERROR) <<
"Timeout (" << start_transition_timeout_ <<
" s) while waiting for Start after receive_fragments thread started!";
346 receiver_thread_active_ =
false;
349 while (receiver_thread_active_)
351 startTime = artdaq::MonitoredQuantity::getCurrentTime();
353 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments getNext start";
354 receiver_thread_active_ = generator_ptr_->getNext(frags);
355 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments getNext done (receiver_thread_active_=" << receiver_thread_active_ <<
")";
363 if (!receiver_thread_active_ && generator_ptr_ && generator_ptr_->exception())
365 parent_application_.in_run_failure();
368 after_input = artdaq::MonitoredQuantity::getCurrentTime();
370 if (!receiver_thread_active_) {
break; }
371 statsHelper_.addSample(FRAGMENTS_PER_READ_STAT_KEY, frags.size());
373 if (frags.size() > 0)
375 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments AddFragmentsToBuffer start";
376 fragment_buffer_ptr_->AddFragmentsToBuffer(std::move(frags));
377 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments AddFragmentsToBuffer done";
380 after_buffer = artdaq::MonitoredQuantity::getCurrentTime();
381 TLOG(TLVL_DEBUG + 34) <<
"receive_fragments INPUT_WAIT=" << (after_input - startTime) <<
", BUFFER_WAIT=" << (after_buffer - after_input);
382 statsHelper_.addSample(INPUT_WAIT_STAT_KEY, after_input - startTime);
383 statsHelper_.addSample(BUFFER_WAIT_STAT_KEY, after_buffer - after_input);
384 if (statsHelper_.statsRollingWindowHasMoved()) { sendMetrics_(); }
391 metricMan->do_stop();
393 TLOG(TLVL_DEBUG + 32) <<
"receive_fragments loop end";
397 if (rt_priority_ > 0)
399 #pragma GCC diagnostic push
400 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
401 sched_param s_param = {};
402 s_param.sched_priority = rt_priority_;
403 if (pthread_setschedparam(pthread_self(), SCHED_RR, &s_param) != 0)
405 TLOG(TLVL_WARNING) <<
"setting realtime priority failed";
407 #pragma GCC diagnostic pop
413 if (rt_priority_ > 0)
415 #pragma GCC diagnostic push
416 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
417 sched_param s_param = {};
418 s_param.sched_priority = rt_priority_;
419 int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
423 <<
"Failed to set realtime priority to " << rt_priority_
424 <<
", return code = " << status;
426 #pragma GCC diagnostic pop
429 TLOG(TLVL_DEBUG + 32) <<
"Initializing DataSenderManager. my_rank=" << my_rank;
430 sender_ptr_ = std::make_unique<artdaq::DataSenderManager>(data_pset_);
432 TLOG(TLVL_DEBUG + 32) <<
"Waiting for first fragment.";
433 artdaq::MonitoredQuantityStats::TIME_POINT_T startTime;
435 artdaq::FragmentPtrs frags;
436 auto targetFragCount = generator_ptr_->fragmentIDs().size();
438 sender_thread_active_ =
true;
440 auto wait_start = std::chrono::steady_clock::now();
441 while (!running_ && TimeUtils::GetElapsedTime(wait_start) < start_transition_timeout_)
447 TLOG(TLVL_ERROR) <<
"Timeout (" << start_transition_timeout_ <<
" s) while waiting for Start after send_fragments thread started!";
448 sender_thread_active_ =
false;
451 while (sender_thread_active_)
453 startTime = artdaq::MonitoredQuantity::getCurrentTime();
455 TLOG(TLVL_DEBUG + 35) <<
"send_fragments applyRequests start";
456 sender_thread_active_ = fragment_buffer_ptr_->applyRequests(frags);
457 TLOG(TLVL_DEBUG + 35) <<
"send_fragments applyRequests done (sender_thread_active_=" << sender_thread_active_ <<
")";
464 if (!sender_thread_active_ && generator_ptr_ && generator_ptr_->exception())
466 parent_application_.in_run_failure();
469 delta_time = artdaq::MonitoredQuantity::getCurrentTime() - startTime;
471 TLOG(TLVL_DEBUG + 34) <<
"send_fragments REQUEST_WAIT=" << delta_time;
472 statsHelper_.addSample(REQUEST_WAIT_STAT_KEY, delta_time);
474 if (!sender_thread_active_) {
break; }
476 for (
auto& fragPtr : frags)
478 if (fragPtr ==
nullptr)
480 TLOG(TLVL_WARNING) <<
"Encountered a bad fragment pointer in fragment " << fragment_count_ <<
". "
481 <<
"This is most likely caused by a problem with the Fragment Generator!";
484 if (fragment_count_ == 0)
486 TLOG(TLVL_DEBUG + 32) <<
"Received first Fragment from Fragment Generator, sequence ID " << fragPtr->sequenceID() <<
", size = " << fragPtr->sizeBytes() <<
" bytes.";
489 if (fragPtr->type() == Fragment::EndOfRunFragmentType || fragPtr->type() == Fragment::EndOfSubrunFragmentType || fragPtr->type() == Fragment::InitFragmentType)
492 artdaq::Fragment::sequence_id_t sequence_id = fragPtr->sequenceID();
493 statsHelper_.addSample(FRAGMENTS_PROCESSED_STAT_KEY, fragPtr->sizeBytes());
495 startTime = artdaq::MonitoredQuantity::getCurrentTime();
496 TLOG(TLVL_DEBUG + 36) <<
"send_fragments seq=" << sequence_id <<
" sendFragment start";
497 auto res = sender_ptr_->sendFragment(std::move(*fragPtr));
500 statsHelper_.addSample(OUTPUT_WAIT_STAT_KEY,
501 artdaq::MonitoredQuantity::getCurrentTime() - startTime);
505 artdaq::Fragment::sequence_id_t sequence_id = fragPtr->sequenceID();
506 SetMFIteration(
"Sequence ID " + std::to_string(sequence_id));
507 statsHelper_.addSample(FRAGMENTS_PROCESSED_STAT_KEY, fragPtr->sizeBytes());
517 if (!skip_seqId_test_ && abs(static_cast<int64_t>(sequence_id) - static_cast<int64_t>(prev_seq_id_)) > 1)
520 <<
"Missing sequence IDs: current sequence ID = "
521 << sequence_id <<
", previous sequence ID = "
522 << prev_seq_id_ <<
".";
524 prev_seq_id_ = sequence_id;
526 startTime = artdaq::MonitoredQuantity::getCurrentTime();
527 TLOG(TLVL_DEBUG + 36) <<
"send_fragments seq=" << sequence_id <<
" sendFragment start";
528 auto res = sender_ptr_->sendFragment(std::move(*fragPtr));
529 if (sender_ptr_->GetSentSequenceIDCount(sequence_id) == targetFragCount)
531 sender_ptr_->RemoveRoutingTableEntry(sequence_id);
535 statsHelper_.addSample(OUTPUT_WAIT_STAT_KEY,
536 artdaq::MonitoredQuantity::getCurrentTime() - startTime);
538 bool readyToReport = statsHelper_.readyToReport();
541 TLOG(TLVL_INFO) << buildStatisticsString_();
545 TLOG(((fragment_count_ == 1) ? TLVL_DEBUG + 32
546 : (((fragment_count_ % 250) == 0 || readyToReport) ? TLVL_DEBUG + 36 : TLVL_DEBUG + 37)))
547 << ((fragment_count_ == 1)
548 ?
"Sent first Fragment"
549 :
"Sending fragment " + std::to_string(fragment_count_))
550 <<
" with SeqID " << sequence_id <<
".";
552 if (statsHelper_.statsRollingWindowHasMoved()) { sendMetrics_(); }
554 std::this_thread::yield();
557 sender_ptr_.reset(
nullptr);
562 metricMan->do_stop();
564 TLOG(TLVL_DEBUG + 32) <<
"send_fragments loop end";
569 std::string resultString;
572 if (generator_ptr_ !=
nullptr && which !=
"core")
574 resultString = generator_ptr_->ReportCmd(which);
575 if (resultString.length() > 0) {
return resultString; }
582 std::string tmpString = app_name +
" run number = ";
583 tmpString.append(boost::lexical_cast<std::string>(run_id_.run()));
585 tmpString.append(
", Sent Fragment count = ");
586 tmpString.append(boost::lexical_cast<std::string>(fragment_count_));
588 if (!which.empty() && which !=
"core")
590 tmpString.append(
". Command=\"" + which +
"\" is not currently supported.");
597 TLOG(TLVL_DEBUG + 32) <<
"metaCommand method called with "
598 <<
"command = \"" << command <<
"\""
599 <<
", arg = \"" << arg <<
"\""
604 return generator_ptr_->metaCommand(command, arg);
610 std::string artdaq::BoardReaderCore::buildStatisticsString_()
612 std::ostringstream oss;
613 double fragmentsGeneratedCount = 1.0;
614 double fragmentsOutputCount = 1.0;
615 oss << app_name <<
" statistics:" << std::endl;
617 oss <<
" Fragments read: ";
618 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PER_READ_STAT_KEY);
619 if (mqPtr.get() !=
nullptr)
621 artdaq::MonitoredQuantityStats stats;
622 mqPtr->getStats(stats);
623 oss << stats.recentSampleCount <<
" fragments generated at "
624 << stats.recentSampleRate <<
" reads/sec, fragment rate = "
625 << stats.recentValueRate <<
" fragments/sec, monitor window = "
626 << stats.recentDuration <<
" sec, min::max read size = "
627 << stats.recentValueMin
629 << stats.recentValueMax
631 fragmentsGeneratedCount = std::max(
double(stats.recentSampleCount), 1.0);
632 oss <<
" Average times per fragment: ";
633 if (stats.recentSampleRate > 0.0)
635 oss <<
" elapsed time = "
636 << (1.0 / stats.recentSampleRate) <<
" sec";
641 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PROCESSED_STAT_KEY);
642 if (mqPtr.get() !=
nullptr)
644 artdaq::MonitoredQuantityStats stats;
645 mqPtr->getStats(stats);
646 oss <<
" Fragment output statistics: "
647 << stats.recentSampleCount <<
" fragments sent at "
648 << stats.recentSampleRate <<
" fragments/sec, effective data rate = "
649 << (stats.recentValueRate *
sizeof(artdaq::RawDataType) / 1024.0 / 1024.0) <<
" MB/sec, monitor window = "
650 << stats.recentDuration <<
" sec, min::max event size = "
651 << (stats.recentValueMin *
sizeof(artdaq::RawDataType) / 1024.0 / 1024.0)
653 << (stats.recentValueMax *
sizeof(artdaq::RawDataType) / 1024.0 / 1024.0)
654 <<
" MB" << std::endl;
655 fragmentsOutputCount = std::max(
double(stats.recentSampleCount), 1.0);
666 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(INPUT_WAIT_STAT_KEY);
667 if (mqPtr.get() !=
nullptr)
669 oss <<
" Input wait time = "
670 << (mqPtr->getRecentValueSum() / fragmentsGeneratedCount) <<
" s/fragment";
672 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(BUFFER_WAIT_STAT_KEY);
673 if (mqPtr.get() != 0)
675 oss <<
", buffer wait time = "
676 << (mqPtr->getRecentValueSum() / fragmentsGeneratedCount) <<
" s/fragment";
678 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(REQUEST_WAIT_STAT_KEY);
679 if (mqPtr.get() != 0)
681 oss <<
", request wait time = "
682 << (mqPtr->getRecentValueSum() / fragmentsOutputCount) <<
" s/fragment";
685 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(OUTPUT_WAIT_STAT_KEY);
686 if (mqPtr.get() !=
nullptr)
688 oss <<
", output wait time = "
689 << (mqPtr->getRecentValueSum() / fragmentsOutputCount) <<
" s/fragment";
695 void artdaq::BoardReaderCore::sendMetrics_()
698 double fragmentCount = 1.0;
699 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PROCESSED_STAT_KEY);
700 if (mqPtr.get() !=
nullptr)
702 artdaq::MonitoredQuantityStats stats;
703 mqPtr->getStats(stats);
704 fragmentCount = std::max(
double(stats.recentSampleCount), 1.0);
705 metricMan->sendMetric(
"Fragment Count", stats.fullSampleCount,
"fragments", 1, MetricMode::LastPoint);
706 metricMan->sendMetric(
"Fragment Rate", stats.recentSampleRate,
"fragments/sec", 1, MetricMode::Average);
707 metricMan->sendMetric(
"Average Fragment Size", (stats.recentValueAverage *
sizeof(artdaq::RawDataType)),
"bytes/fragment", 2, MetricMode::Average);
708 metricMan->sendMetric(
"Data Rate", (stats.recentValueRate *
sizeof(artdaq::RawDataType)),
"bytes/sec", 2, MetricMode::Average);
719 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(INPUT_WAIT_STAT_KEY);
720 if (mqPtr.get() !=
nullptr)
722 metricMan->sendMetric(
"Avg Input Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
725 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(BUFFER_WAIT_STAT_KEY);
726 if (mqPtr.get() != 0)
728 metricMan->sendMetric(
"Avg Buffer Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
730 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(REQUEST_WAIT_STAT_KEY);
731 if (mqPtr.get() != 0)
733 metricMan->sendMetric(
"Avg Request Response Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
735 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(OUTPUT_WAIT_STAT_KEY);
736 if (mqPtr.get() !=
nullptr)
738 metricMan->sendMetric(
"Avg Output Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
741 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PER_READ_STAT_KEY);
742 if (mqPtr.get() !=
nullptr)
744 metricMan->sendMetric(
"Avg Frags Per Read", mqPtr->getRecentValueAverage(),
"fragments/read", 4, MetricMode::Average);
static const std::string BUFFER_WAIT_STAT_KEY
Key for the Fragment Buffer Wait MonitoredQuantity.
void addMonitoredQuantityName(std::string const &statKey)
Add a MonitoredQuantity name to the list.
Commandable is the base class for all artdaq components which implement the artdaq state machine...
bool initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Initialize the BoardReaderCore.
static const std::string FRAGMENTS_PROCESSED_STAT_KEY
Key for the Fragments Processed MonitoredQuantity.
bool reinitialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Reinitialize the BoardReader. No-Op.
static const std::string INPUT_WAIT_STAT_KEY
Key for the Input Wait MonitoredQuantity.
bool stop(uint64_t timeout, uint64_t timestamp)
Stop the BoardReader, and the CommandableFragmentGenerator.
virtual ~BoardReaderCore()
BoardReaderCore Destructor.
static std::string CopyStatusToString(CopyStatus in)
Convert a CopyStatus variable to its string represenatation
BoardReaderCore(Commandable &parent_application)
BoardReaderCore Constructor.
std::unique_ptr< CommandableFragmentGenerator > makeCommandableFragmentGenerator(std::string const &generator_plugin_spec, fhicl::ParameterSet const &ps)
Load a CommandableFragmentGenerator plugin.
Receive data requests and make them available to CommandableFragmentGenerator or other interested par...
static const std::string FRAGMENTS_PER_READ_STAT_KEY
Key for the Fragments Per Read MonitoredQuantity.
static const std::string REQUEST_WAIT_STAT_KEY
Key for the Request Buffer Wait MonitoredQuantity.
static const std::string OUTPUT_WAIT_STAT_KEY
Key for the Output Wait MonitoredQuantity.
void send_fragments()
Main working loop of the BoardReaderCore, pt. 2.
bool soft_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp)
Soft-Initialize the BoardReader. No-Op.
std::string report(std::string const &which) const
Send a report on a given run-time quantity.
bool shutdown(uint64_t timeout)
Shutdown the BoardReader, and the CommandableFragmentGenerator.
bool start(art::RunID id, uint64_t timeout, uint64_t timestamp)
Start the BoardReader, and the CommandableFragmentGenerator.
bool resume(uint64_t timeout, uint64_t timestamp)
Resume the BoardReader, and the CommandableFragmentGenerator.
void receive_fragments()
Main working loop of the BoardReaderCore.
bool pause(uint64_t timeout, uint64_t timestamp)
Pause the BoardReader, and the CommandableFragmentGenerator.
bool metaCommand(std::string const &command, std::string const &arg)
Run a user-defined command on the CommandableFragmentGenerator.