|
13 | 13 |
|
14 | 14 | #include "StfBuilderDevice.h" |
15 | 15 |
|
| 16 | +#include <DataDistLogger.h> |
16 | 17 | #include <SubTimeFrameUtils.h> |
17 | 18 | #include <SubTimeFrameVisitors.h> |
18 | 19 | #include <ReadoutDataModel.h> |
|
21 | 22 | #include <Utilities.h> |
22 | 23 |
|
23 | 24 | #include <options/FairMQProgOptions.h> |
| 25 | +#include <Framework/SourceInfoHeader.h> |
24 | 26 |
|
25 | 27 | #include <chrono> |
26 | 28 | #include <thread> |
27 | 29 | #include <exception> |
28 | 30 | #include <boost/algorithm/string.hpp> |
29 | 31 |
|
30 | | -#include <DataDistLogger.h> |
31 | | - |
32 | 32 | namespace o2 |
33 | 33 | { |
34 | 34 | namespace DataDistribution |
@@ -94,6 +94,7 @@ void StfBuilderDevice::InitTask() |
94 | 94 | I().mDplChannelName = GetConfig()->GetValue<std::string>(OptionKeyDplChannelName); |
95 | 95 | I().mStandalone = GetConfig()->GetValue<bool>(OptionKeyStandalone); |
96 | 96 | I().mMaxStfsInPipeline = GetConfig()->GetValue<std::int64_t>(OptionKeyMaxBufferedStfs); |
| 97 | + I().mMaxBuiltStfs = GetConfig()->GetValue<std::uint64_t>(OptionKeyMaxBuiltStfs); |
97 | 98 |
|
98 | 99 | // input data handling |
99 | 100 | ReadoutDataUtils::sSpecifiedDataOrigin = getDataOriginFromOption( |
@@ -127,6 +128,10 @@ void StfBuilderDevice::InitTask() |
127 | 128 | "Possibility of creating back-pressure."); |
128 | 129 | } |
129 | 130 |
|
| 131 | + // Limited number of STF? |
| 132 | + DDLOGF(fair::Severity::INFO, "Configuration: Number of built SubTimeFrames is {}", |
| 133 | + I().mMaxBuiltStfs == 0 ? "not limited" : ("limited to " + std::to_string(I().mMaxBuiltStfs))); |
| 134 | + |
130 | 135 | // File sink |
131 | 136 | if (!I().mFileSink->loadVerifyConfig(*(this->GetConfig()))) { |
132 | 137 | exit(-1); |
@@ -254,6 +259,9 @@ void StfBuilderDevice::ResetTask() |
254 | 259 | { |
255 | 260 | DDLOGF(fair::Severity::DEBUG, "StfBuilderDevice::ResetTask()"); |
256 | 261 |
|
| 262 | + // Signal ConditionalRun() and other threads to stop |
| 263 | + I().mRunning = false; |
| 264 | + |
257 | 265 | // stop the memory resources |
258 | 266 | MemI().stop(); |
259 | 267 |
|
@@ -364,11 +372,41 @@ void StfBuilderDevice::StfOutputThread() |
364 | 372 | const double lTimeMs = std::max(1e-6, std::chrono::duration<double, std::milli>(lNow - lSendStartTime).count()); |
365 | 373 | I().mSentOutRate = double(I().mSentOutStfs) / std::chrono::duration<double>(lNow - sStartOfStfSending).count(); |
366 | 374 | I().mStfDataTimeSamples.Fill(lTimeMs); |
367 | | - } else { |
368 | | - // DDLOGF(fair::Severity::ERROR, "Dropping stf size={}", lStf->getDataSize()); |
| 375 | + } |
| 376 | + |
| 377 | + // check if we should exit: |
| 378 | + // 1. max number of stf set, or |
| 379 | + // 2. file reply used without loop parameter |
| 380 | + if ( (I().mMaxBuiltStfs > 0) && (I().mSentOutStfsTotal == I().mMaxBuiltStfs) ) { |
| 381 | + DDLOGF(fair::Severity::INFO, "Maximum number of sent SubTimeFrames reached. Exiting."); |
| 382 | + break; |
369 | 383 | } |
370 | 384 | } |
371 | 385 |
|
| 386 | + // leaving the output thread, send end of the stream info |
| 387 | + if (dplEnabled()) { |
| 388 | + o2::framework::SourceInfoHeader lDplExitHdr; |
| 389 | + lDplExitHdr.state = o2::framework::InputChannelState::Completed; |
| 390 | + auto lDoneStack = Stack( |
| 391 | + DataHeader(gDataDescriptionInfo, gDataOriginAny, 0, 0), |
| 392 | + o2::framework::DataProcessingHeader(), |
| 393 | + lDplExitHdr |
| 394 | + ); |
| 395 | + |
| 396 | + // Send a multipart |
| 397 | + FairMQParts lCompletedMsg; |
| 398 | + auto lNoFree = [](void*, void*) { /* stack */ }; |
| 399 | + lCompletedMsg.AddPart(lOutputChan.NewMessage(lDoneStack.data(), lDoneStack.size(), lNoFree)); |
| 400 | + lCompletedMsg.AddPart(lOutputChan.NewMessage()); |
| 401 | + lOutputChan.Send(lCompletedMsg); |
| 402 | + |
| 403 | + DDLOGF(fair::Severity::INFO, "Sent Source Completed message to DPL."); |
| 404 | + // NOTE: no guarantees this will be sent out |
| 405 | + std::this_thread::sleep_for(2s); |
| 406 | + } |
| 407 | + |
| 408 | + I().mRunning = false; // trigger stop via CondRun() |
| 409 | + |
372 | 410 | DDLOGF(fair::Severity::info, "Exiting StfOutputThread..."); |
373 | 411 | } |
374 | 412 |
|
@@ -397,7 +435,12 @@ bool StfBuilderDevice::ConditionalRun() |
397 | 435 | { |
398 | 436 | // nothing to do here sleep for awhile |
399 | 437 | std::this_thread::sleep_for(500ms); |
400 | | - return true; |
| 438 | + |
| 439 | + if (!I().mRunning) { |
| 440 | + DDLOGF(fair::Severity::DEBUG, "ConditionalRun() returning false."); |
| 441 | + } |
| 442 | + |
| 443 | + return I().mRunning; |
401 | 444 | } |
402 | 445 |
|
403 | 446 | bpo::options_description StfBuilderDevice::getDetectorProgramOptions() { |
|
0 commit comments