1 #include "artdaq/DAQdata/Globals.hh"
2 #define TRACE_NAME (app_name + "_BoardReaderCore").c_str()
4 #include "artdaq-core/Core/MonitoredQuantity.hh"
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"
11 #include "cetlib_except/exception.h"
12 #include "fhiclcpp/ParameterSet.h"
14 #include <boost/lexical_cast.hpp>
33 std::unique_ptr<artdaq::DataSenderManager> artdaq::BoardReaderCore::sender_ptr_ =
nullptr;
36 : parent_application_(parent_application)
38 , generator_ptr_(nullptr)
39 , run_id_(art::RunID::flushRun())
41 , stop_requested_(false)
42 , pause_requested_(false)
44 TLOG(TLVL_DEBUG + 32) <<
"Constructor";
55 TLOG(TLVL_DEBUG + 32) <<
"Destructor";
56 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request Receiver BEGIN";
57 request_receiver_ptr_.reset(
nullptr);
58 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request Receiver END";
63 TLOG(TLVL_DEBUG + 32) <<
"initialize method called with "
64 <<
"ParameterSet = \"" << pset.to_string() <<
"\".";
67 fhicl::ParameterSet daq_pset;
70 daq_pset = pset.get<fhicl::ParameterSet>(
"daq");
75 <<
"Unable to find the DAQ parameters in the initialization "
76 <<
"ParameterSet: \"" + pset.to_string() +
"\".";
79 fhicl::ParameterSet fr_pset;
82 fr_pset = daq_pset.get<fhicl::ParameterSet>(
"fragment_receiver");
88 <<
"Unable to find the fragment_receiver parameters in the DAQ "
89 <<
"initialization ParameterSet: \"" + daq_pset.to_string() +
"\".";
94 fhicl::ParameterSet metric_pset;
97 metric_pset = daq_pset.get<fhicl::ParameterSet>(
"metrics");
102 if (metric_pset.is_empty())
104 TLOG(TLVL_INFO) <<
"No metric plugins appear to be defined";
108 metricMan->initialize(metric_pset, app_name);
112 ExceptionHandler(ExceptionHandlerRethrow::no,
113 "Error loading metrics in BoardReaderCore::initialize()");
116 if (daq_pset.has_key(
"rank"))
118 if (my_rank >= 0 && daq_pset.get<
int>(
"rank") != my_rank)
120 TLOG(TLVL_WARNING) <<
"BoardReader rank specified at startup is different than rank specified at configure! Using rank received at configure!";
122 my_rank = daq_pset.get<
int>(
"rank");
126 TLOG(TLVL_ERROR) <<
"BoardReader rank not specified at startup or in configuration! Aborting";
127 throw cet::exception(
"RankNotSpecifiedError") <<
"BoardReader rank not specified at startup or in configuration! Aborting";
131 auto frag_gen_name = fr_pset.get<std::string>(
"generator",
"");
132 if (frag_gen_name.length() == 0)
135 <<
"No fragment generator (parameter name = \"generator\") was "
136 <<
"specified in the fragment_receiver ParameterSet. The "
137 <<
"DAQ initialization PSet was \"" << daq_pset.to_string() <<
"\".";
147 std::stringstream exception_string;
148 exception_string <<
"Exception thrown during initialization of fragment generator of type \""
149 << frag_gen_name <<
"\"";
151 ExceptionHandler(ExceptionHandlerRethrow::no, exception_string.str());
153 TLOG(TLVL_DEBUG + 32) <<
"FHiCL parameter set used to initialize the fragment generator which threw an exception: " << fr_pset.to_string();
160 fragment_buffer_ptr_ = std::make_shared<FragmentBuffer>(fr_pset);
164 std::stringstream exception_string;
165 exception_string <<
"Exception thrown during initialization of Fragment Buffer";
167 ExceptionHandler(ExceptionHandlerRethrow::no, exception_string.str());
169 TLOG(TLVL_DEBUG + 32) <<
"FHiCL parameter set used to initialize the fragment buffer which threw an exception: " << fr_pset.to_string();
174 std::shared_ptr<RequestBuffer> request_buffer = std::make_shared<RequestBuffer>(fr_pset.get<artdaq::Fragment::sequence_id_t>(
"request_increment", 1));
178 request_receiver_ptr_.reset(
new RequestReceiver(fr_pset, request_buffer));
179 generator_ptr_->SetRequestBuffer(request_buffer);
180 generator_ptr_->SetFragmentBuffer(fragment_buffer_ptr_);
181 fragment_buffer_ptr_->SetRequestBuffer(request_buffer);
185 ExceptionHandler(ExceptionHandlerRethrow::no,
"Exception thrown during initialization of request receiver");
187 TLOG(TLVL_DEBUG + 32) <<
"FHiCL parameter set used to initialize the request receiver which threw an exception: " << fr_pset.to_string();
191 metricMan->setPrefix(generator_ptr_->metricsReportingInstanceName());
193 rt_priority_ = fr_pset.get<
int>(
"rt_priority", 0);
196 statsHelper_.createCollectors(fr_pset, 100, 30.0, 60.0, FRAGMENTS_PROCESSED_STAT_KEY);
199 skip_seqId_test_ = (fr_pset.get<
bool>(
"skip_seqID_test",
false) || generator_ptr_->fragmentIDs().size() > 1 || fragment_buffer_ptr_->request_mode() != RequestMode::Ignored);
201 verbose_ = fr_pset.get<
bool>(
"verbose",
true);
208 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Starting run " <<
id.run();
209 stop_requested_.store(
false);
210 pause_requested_.store(
false);
214 statsHelper_.resetStatistics();
216 fragment_buffer_ptr_->Reset(
false);
218 metricMan->do_start();
219 generator_ptr_->StartCmd(
id.run(), timeout, timestamp);
222 request_receiver_ptr_->SetRunNumber(static_cast<uint32_t>(
id.run()));
223 request_receiver_ptr_->startRequestReception();
226 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Start transition (Started run) for run " << run_id_.run()
227 <<
", timeout = " << timeout <<
", timestamp = " << timestamp;
233 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Stopping run " << run_id_.run() <<
" after " << fragment_count_ <<
" fragments.";
234 stop_requested_.store(
true);
236 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request reception BEGIN";
237 request_receiver_ptr_->stopRequestReception();
238 TLOG(TLVL_DEBUG + 32) <<
"Stopping Request reception END";
240 TLOG(TLVL_DEBUG + 32) <<
"Stopping CommandableFragmentGenerator BEGIN";
241 generator_ptr_->StopCmd(timeout, timestamp);
242 TLOG(TLVL_DEBUG + 32) <<
"Stopping CommandableFragmentGenerator END";
244 TLOG(TLVL_DEBUG + 32) <<
"Stopping FragmentBuffer";
245 fragment_buffer_ptr_->Stop();
247 TLOG(TLVL_DEBUG + 32) <<
"Stopping DataSenderManager";
250 sender_ptr_->StopSender();
254 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Stop transition for run " << run_id_.run();
260 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Pausing run " << run_id_.run() <<
" after " << fragment_count_ <<
" fragments.";
261 pause_requested_.store(
true);
262 generator_ptr_->PauseCmd(timeout, timestamp);
263 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Pause transition for run " << run_id_.run();
269 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Resuming run " << run_id_.run();
270 pause_requested_.store(
false);
271 metricMan->do_start();
272 generator_ptr_->ResumeCmd(timeout, timestamp);
273 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed the Resume transition for run " << run_id_.run();
279 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Starting Shutdown transition";
280 generator_ptr_->joinThreads();
281 generator_ptr_.reset(
nullptr);
282 metricMan->shutdown();
283 TLOG((verbose_ ? TLVL_INFO : TLVL_DEBUG + 32)) <<
"Completed Shutdown transition";
289 TLOG(TLVL_DEBUG + 32) <<
"soft_initialize method called with "
290 <<
"ParameterSet = \"" << pset.to_string()
291 <<
"\". Forwarding to initialize.";
292 return initialize(pset, timeout, timestamp);
297 TLOG(TLVL_DEBUG + 32) <<
"reinitialize method called with "
298 <<
"ParameterSet = \"" << pset.to_string()
299 <<
"\". Forwarding to initalize.";
300 return initialize(pset, timeout, timestamp);
305 if (rt_priority_ > 0)
307 #pragma GCC diagnostic push
308 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
309 sched_param s_param = {};
310 s_param.sched_priority = rt_priority_;
311 if (pthread_setschedparam(pthread_self(), SCHED_RR, &s_param))
312 TLOG(TLVL_WARNING) <<
"setting realtime priority failed";
313 #pragma GCC diagnostic pop
319 if (rt_priority_ > 0)
321 #pragma GCC diagnostic push
322 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
323 sched_param s_param = {};
324 s_param.sched_priority = rt_priority_;
325 int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
329 <<
"Failed to set realtime priority to " << rt_priority_
330 <<
", return code = " << status;
332 #pragma GCC diagnostic pop
335 TLOG(TLVL_DEBUG + 32) <<
"Waiting for first fragment.";
336 artdaq::MonitoredQuantityStats::TIME_POINT_T startTime, after_input, after_buffer;
337 artdaq::FragmentPtrs frags;
339 receiver_thread_active_ =
true;
341 auto wait_start = std::chrono::steady_clock::now();
342 while (!running_ && TimeUtils::GetElapsedTime(wait_start) < start_transition_timeout_)
348 TLOG(TLVL_ERROR) <<
"Timeout (" << start_transition_timeout_ <<
" s) while waiting for Start after receive_fragments thread started!";
349 receiver_thread_active_ =
false;
352 while (receiver_thread_active_)
354 startTime = artdaq::MonitoredQuantity::getCurrentTime();
356 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments getNext start";
357 receiver_thread_active_ = generator_ptr_->getNext(frags);
358 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments getNext done (receiver_thread_active_=" << receiver_thread_active_ <<
")";
366 if (!receiver_thread_active_ && generator_ptr_ && generator_ptr_->exception())
368 parent_application_.in_run_failure();
371 after_input = artdaq::MonitoredQuantity::getCurrentTime();
373 if (!receiver_thread_active_) {
break; }
374 statsHelper_.addSample(FRAGMENTS_PER_READ_STAT_KEY, frags.size());
376 if (frags.size() > 0)
378 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments AddFragmentsToBuffer start";
379 fragment_buffer_ptr_->AddFragmentsToBuffer(std::move(frags));
380 TLOG(TLVL_DEBUG + 35) <<
"receive_fragments AddFragmentsToBuffer done";
383 after_buffer = artdaq::MonitoredQuantity::getCurrentTime();
384 TLOG(TLVL_DEBUG + 34) <<
"receive_fragments INPUT_WAIT=" << (after_input - startTime) <<
", BUFFER_WAIT=" << (after_buffer - after_input);
385 statsHelper_.addSample(INPUT_WAIT_STAT_KEY, after_input - startTime);
386 statsHelper_.addSample(BUFFER_WAIT_STAT_KEY, after_buffer - after_input);
387 if (statsHelper_.statsRollingWindowHasMoved()) { sendMetrics_(); }
394 metricMan->do_stop();
396 TLOG(TLVL_DEBUG + 32) <<
"receive_fragments loop end";
400 if (rt_priority_ > 0)
402 #pragma GCC diagnostic push
403 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
404 sched_param s_param = {};
405 s_param.sched_priority = rt_priority_;
406 if (pthread_setschedparam(pthread_self(), SCHED_RR, &s_param) != 0)
408 TLOG(TLVL_WARNING) <<
"setting realtime priority failed";
410 #pragma GCC diagnostic pop
416 if (rt_priority_ > 0)
418 #pragma GCC diagnostic push
419 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
420 sched_param s_param = {};
421 s_param.sched_priority = rt_priority_;
422 int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
426 <<
"Failed to set realtime priority to " << rt_priority_
427 <<
", return code = " << status;
429 #pragma GCC diagnostic pop
432 TLOG(TLVL_DEBUG + 32) <<
"Initializing DataSenderManager. my_rank=" << my_rank;
433 sender_ptr_ = std::make_unique<artdaq::DataSenderManager>(data_pset_);
435 TLOG(TLVL_DEBUG + 32) <<
"Waiting for first fragment.";
436 artdaq::MonitoredQuantityStats::TIME_POINT_T startTime;
438 artdaq::FragmentPtrs frags;
439 auto targetFragCount = generator_ptr_->fragmentIDs().size();
441 sender_thread_active_ =
true;
443 auto wait_start = std::chrono::steady_clock::now();
444 while (!running_ && TimeUtils::GetElapsedTime(wait_start) < start_transition_timeout_)
450 TLOG(TLVL_ERROR) <<
"Timeout (" << start_transition_timeout_ <<
" s) while waiting for Start after send_fragments thread started!";
451 sender_thread_active_ =
false;
454 while (sender_thread_active_)
456 startTime = artdaq::MonitoredQuantity::getCurrentTime();
458 TLOG(TLVL_DEBUG + 35) <<
"send_fragments applyRequests start";
459 sender_thread_active_ = fragment_buffer_ptr_->applyRequests(frags);
460 TLOG(TLVL_DEBUG + 35) <<
"send_fragments applyRequests done (sender_thread_active_=" << sender_thread_active_ <<
")";
467 if (!sender_thread_active_ && generator_ptr_ && generator_ptr_->exception())
469 parent_application_.in_run_failure();
472 delta_time = artdaq::MonitoredQuantity::getCurrentTime() - startTime;
474 TLOG(TLVL_DEBUG + 34) <<
"send_fragments REQUEST_WAIT=" << delta_time;
475 statsHelper_.addSample(REQUEST_WAIT_STAT_KEY, delta_time);
477 if (!sender_thread_active_) {
break; }
479 for (
auto& fragPtr : frags)
481 if (fragPtr ==
nullptr)
483 TLOG(TLVL_WARNING) <<
"Encountered a bad fragment pointer in fragment " << fragment_count_ <<
". "
484 <<
"This is most likely caused by a problem with the Fragment Generator!";
487 if (fragment_count_ == 0)
489 TLOG(TLVL_DEBUG + 32) <<
"Received first Fragment from Fragment Generator, sequence ID " << fragPtr->sequenceID() <<
", size = " << fragPtr->sizeBytes() <<
" bytes.";
492 if (fragPtr->type() == Fragment::EndOfRunFragmentType || fragPtr->type() == Fragment::EndOfSubrunFragmentType || fragPtr->type() == Fragment::InitFragmentType)
495 artdaq::Fragment::sequence_id_t sequence_id = fragPtr->sequenceID();
496 statsHelper_.addSample(FRAGMENTS_PROCESSED_STAT_KEY, fragPtr->sizeBytes());
498 startTime = artdaq::MonitoredQuantity::getCurrentTime();
499 TLOG(TLVL_DEBUG + 36) <<
"send_fragments seq=" << sequence_id <<
" sendFragment start";
500 auto res = sender_ptr_->sendFragment(std::move(*fragPtr));
503 statsHelper_.addSample(OUTPUT_WAIT_STAT_KEY,
504 artdaq::MonitoredQuantity::getCurrentTime() - startTime);
508 artdaq::Fragment::sequence_id_t sequence_id = fragPtr->sequenceID();
509 SetMFIteration(
"Sequence ID " + std::to_string(sequence_id));
510 statsHelper_.addSample(FRAGMENTS_PROCESSED_STAT_KEY, fragPtr->sizeBytes());
520 if (!skip_seqId_test_ && abs(static_cast<int64_t>(sequence_id) - static_cast<int64_t>(prev_seq_id_)) > 1)
523 <<
"Missing sequence IDs: current sequence ID = "
524 << sequence_id <<
", previous sequence ID = "
525 << prev_seq_id_ <<
".";
527 prev_seq_id_ = sequence_id;
529 startTime = artdaq::MonitoredQuantity::getCurrentTime();
530 TLOG(TLVL_DEBUG + 36) <<
"send_fragments seq=" << sequence_id <<
" sendFragment start";
531 auto res = sender_ptr_->sendFragment(std::move(*fragPtr));
532 if (sender_ptr_->GetSentSequenceIDCount(sequence_id) == targetFragCount)
534 sender_ptr_->RemoveRoutingTableEntry(sequence_id);
538 statsHelper_.addSample(OUTPUT_WAIT_STAT_KEY,
539 artdaq::MonitoredQuantity::getCurrentTime() - startTime);
541 bool readyToReport = statsHelper_.readyToReport();
544 TLOG(TLVL_INFO) << buildStatisticsString_();
548 TLOG(((fragment_count_ == 1) ? TLVL_DEBUG + 32
549 : (((fragment_count_ % 250) == 0 || readyToReport) ? TLVL_DEBUG + 36 : TLVL_DEBUG + 37)))
550 << ((fragment_count_ == 1)
551 ?
"Sent first Fragment"
552 :
"Sending fragment " + std::to_string(fragment_count_))
553 <<
" with SeqID " << sequence_id <<
".";
555 if (statsHelper_.statsRollingWindowHasMoved()) { sendMetrics_(); }
557 std::this_thread::yield();
560 sender_ptr_.reset(
nullptr);
565 metricMan->do_stop();
567 TLOG(TLVL_DEBUG + 32) <<
"send_fragments loop end";
572 std::string resultString;
575 if (generator_ptr_ !=
nullptr && which !=
"core")
577 resultString = generator_ptr_->ReportCmd(which);
578 if (resultString.length() > 0) {
return resultString; }
585 std::string tmpString = app_name +
" run number = ";
586 tmpString.append(boost::lexical_cast<std::string>(run_id_.run()));
588 tmpString.append(
", Sent Fragment count = ");
589 tmpString.append(boost::lexical_cast<std::string>(fragment_count_));
591 if (!which.empty() && which !=
"core")
593 tmpString.append(
". Command=\"" + which +
"\" is not currently supported.");
600 TLOG(TLVL_DEBUG + 32) <<
"metaCommand method called with "
601 <<
"command = \"" << command <<
"\""
602 <<
", arg = \"" << arg <<
"\""
607 return generator_ptr_->metaCommand(command, arg);
613 std::string artdaq::BoardReaderCore::buildStatisticsString_()
615 std::ostringstream oss;
616 double fragmentsGeneratedCount = 1.0;
617 double fragmentsOutputCount = 1.0;
618 oss << app_name <<
" statistics:" << std::endl;
620 oss <<
" Fragments read: ";
621 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PER_READ_STAT_KEY);
622 if (mqPtr.get() !=
nullptr)
624 artdaq::MonitoredQuantityStats stats;
625 mqPtr->getStats(stats);
626 oss << stats.recentValueSum <<
" fragments generated at "
627 << stats.recentSampleRate <<
" getNext calls/sec, fragment rate = "
628 << stats.recentValueRate <<
" fragments/sec, monitor window = "
629 << stats.recentDuration <<
" sec, min::max read size = "
630 << stats.recentValueMin
632 << stats.recentValueMax
634 fragmentsGeneratedCount = std::max(
double(stats.recentSampleCount), 1.0);
635 oss <<
" Average times per fragment: ";
636 if (stats.recentSampleRate > 0.0)
638 oss <<
" elapsed time = "
639 << (1.0 / stats.recentSampleRate) <<
" sec";
644 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PROCESSED_STAT_KEY);
645 if (mqPtr.get() !=
nullptr)
647 artdaq::MonitoredQuantityStats stats;
648 mqPtr->getStats(stats);
649 oss <<
" Fragment output statistics: "
650 << stats.recentSampleCount <<
" fragments sent at "
651 << stats.recentSampleRate <<
" fragments/sec, effective data rate = "
652 << (stats.recentValueRate / 1024.0 / 1024.0) <<
" MB/sec, monitor window = "
653 << stats.recentDuration <<
" sec, min::max event size = "
654 << (stats.recentValueMin / 1024.0 / 1024.0)
656 << (stats.recentValueMax / 1024.0 / 1024.0)
657 <<
" MB" << std::endl;
658 fragmentsOutputCount = std::max(
double(stats.recentSampleCount), 1.0);
669 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(INPUT_WAIT_STAT_KEY);
670 if (mqPtr.get() !=
nullptr)
672 oss <<
" Input wait time = "
673 << (mqPtr->getRecentValueSum() / fragmentsGeneratedCount) <<
" s/fragment";
675 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(BUFFER_WAIT_STAT_KEY);
676 if (mqPtr.get() != 0)
678 oss <<
", buffer wait time = "
679 << (mqPtr->getRecentValueSum() / fragmentsGeneratedCount) <<
" s/fragment";
681 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(REQUEST_WAIT_STAT_KEY);
682 if (mqPtr.get() != 0)
684 oss <<
", request wait time = "
685 << (mqPtr->getRecentValueSum() / fragmentsOutputCount) <<
" s/fragment";
688 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(OUTPUT_WAIT_STAT_KEY);
689 if (mqPtr.get() !=
nullptr)
691 oss <<
", output wait time = "
692 << (mqPtr->getRecentValueSum() / fragmentsOutputCount) <<
" s/fragment";
698 void artdaq::BoardReaderCore::sendMetrics_()
701 double fragmentCount = 1.0;
702 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PROCESSED_STAT_KEY);
703 if (mqPtr.get() !=
nullptr)
705 artdaq::MonitoredQuantityStats stats;
706 mqPtr->getStats(stats);
707 fragmentCount = std::max(
double(stats.recentSampleCount), 1.0);
708 metricMan->sendMetric(
"Fragment Count", stats.fullSampleCount,
"fragments", 1, MetricMode::LastPoint);
709 metricMan->sendMetric(
"Fragment Rate", stats.recentSampleRate,
"fragments/sec", 1, MetricMode::Average);
710 metricMan->sendMetric(
"Average Fragment Size", stats.recentValueAverage,
"bytes/fragment", 2, MetricMode::Average);
711 metricMan->sendMetric(
"Data Rate", stats.recentValueRate,
"bytes/sec", 2, MetricMode::Average);
722 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(INPUT_WAIT_STAT_KEY);
723 if (mqPtr.get() !=
nullptr)
725 metricMan->sendMetric(
"Avg Input Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
728 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(BUFFER_WAIT_STAT_KEY);
729 if (mqPtr.get() != 0)
731 metricMan->sendMetric(
"Avg Buffer Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
733 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(REQUEST_WAIT_STAT_KEY);
734 if (mqPtr.get() != 0)
736 metricMan->sendMetric(
"Avg Request Response Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
738 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(OUTPUT_WAIT_STAT_KEY);
739 if (mqPtr.get() !=
nullptr)
741 metricMan->sendMetric(
"Avg Output Wait Time", (mqPtr->getRecentValueSum() / fragmentCount),
"seconds/fragment", 3, MetricMode::Average);
744 mqPtr = artdaq::StatisticsCollection::getInstance().getMonitoredQuantity(FRAGMENTS_PER_READ_STAT_KEY);
745 if (mqPtr.get() !=
nullptr)
747 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.