Skip to content

Commit 3c7821e

Browse files
authored
[QC-429] Use CCDB RCT as the first source for SOR/EOR in async QC (#1850)
1 parent ee90945 commit 3c7821e

10 files changed

Lines changed: 79 additions & 34 deletions

Framework/include/QualityControl/ActivityHelpers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ std::map<std::string, std::string> asDatabaseMetadata(const core::Activity&, boo
8888
core::Activity asActivity(const std::map<std::string, std::string>& metadata, const std::string& provenance = "qc");
8989
core::Activity asActivity(const boost::property_tree::ptree&, const std::string& provenance = "qc");
9090

91+
std::function<validity_time_t(void)> getCcdbSorTimeAccessor(uint64_t runNumber);
92+
std::function<validity_time_t(void)> getCcdbEorTimeAccessor(uint64_t runNumber);
93+
9194
namespace implementation
9295
{
9396
template <typename Iter, typename Accessor>

Framework/include/QualityControl/Timekeeper.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define QUALITYCONTROL_TIMEKEEPER_H
1919

2020
#include "QualityControl/ValidityInterval.h"
21+
#include <functional>
2122

2223
namespace o2::framework
2324
{
@@ -43,9 +44,11 @@ class Timekeeper
4344
/// \brief sets activity (run) duration
4445
void setActivityDuration(ValidityInterval);
4546
/// \brief sets start of activity (run), but prioritises the source of information according to the class implementation
46-
void setStartOfActivity(validity_time_t ecsTimestamp = 0, validity_time_t configTimestamp = 0, validity_time_t currentTimestamp = 0);
47+
void setStartOfActivity(validity_time_t ecsTimestamp = 0, validity_time_t configTimestamp = 0,
48+
validity_time_t currentTimestamp = 0, std::function<validity_time_t(void)> ccdbTimestampAccessor = nullptr);
4749
/// \brief sets end of activity (run), but prioritises the source of information according to the class implementation
48-
void setEndOfActivity(validity_time_t ecsTimestamp = 0, validity_time_t configTimestamp = 0, validity_time_t currentTimestamp = 0);
50+
void setEndOfActivity(validity_time_t ecsTimestamp = 0, validity_time_t configTimestamp = 0, validity_time_t currentTimestamp = 0,
51+
std::function<validity_time_t(void)> ccdbTimestampAccessor = nullptr);
4952

5053
/// \brief updates the validity based on the provided timestamp (ms since epoch)
5154
virtual void updateByCurrentTimestamp(validity_time_t timestampMs) = 0;
@@ -62,9 +65,12 @@ class Timekeeper
6265

6366
protected:
6467
/// \brief defines how a class implementation chooses the activity (run) boundaries
65-
virtual validity_time_t activityBoundarySelectionStrategy(validity_time_t ecsTimestamp,
66-
validity_time_t configTimestamp,
67-
validity_time_t currentTimestamp) = 0;
68+
// by using an accessor to ccdb, we do not call if we are not interested
69+
virtual validity_time_t
70+
activityBoundarySelectionStrategy(validity_time_t ecsTimestamp,
71+
validity_time_t configTimestamp,
72+
validity_time_t currentTimestamp,
73+
std::function<validity_time_t(void)> ccdbTimestampAccessor) = 0;
6874

6975
protected:
7076
ValidityInterval mActivityDuration = gInvalidValidityInterval; // from O2StartTime to O2EndTime or current timestamp

Framework/include/QualityControl/TimekeeperAsynchronous.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ class TimekeeperAsynchronous : public Timekeeper
3333
void reset() override;
3434

3535
protected:
36-
validity_time_t activityBoundarySelectionStrategy(validity_time_t ecsTimestamp,
37-
validity_time_t configTimestamp,
38-
validity_time_t currentTimestamp) override;
36+
validity_time_t activityBoundarySelectionStrategy(validity_time_t ecsTimestamp, validity_time_t configTimestamp,
37+
validity_time_t currentTimestamp,
38+
std::function<validity_time_t(void)> ccdbTimestampAccessor) override;
3939

4040
private:
4141
validity_time_t mWindowLengthMs = 0;

Framework/include/QualityControl/TimekeeperSynchronous.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ class TimekeeperSynchronous : public Timekeeper
3434
void reset() override;
3535

3636
protected:
37-
validity_time_t activityBoundarySelectionStrategy(validity_time_t ecsTimestamp,
38-
validity_time_t configTimestamp,
39-
validity_time_t currentTimestamp) override;
37+
validity_time_t activityBoundarySelectionStrategy(validity_time_t ecsTimestamp, validity_time_t configTimestamp,
38+
validity_time_t currentTimestamp,
39+
std::function<validity_time_t(void)> ccdbTimestampAccessor) override;
4040

4141
private:
4242
bool mWarnedAboutDataWithoutSOR = false;

Framework/src/ActivityHelpers.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
///
1616

1717
#include "QualityControl/ActivityHelpers.h"
18+
1819
#include <boost/property_tree/ptree.hpp>
20+
#include <CCDB/BasicCCDBManager.h>
1921
#include "QualityControl/ObjectMetadataKeys.h"
2022

2123
using namespace o2::quality_control::repository;
@@ -93,4 +95,14 @@ core::Activity asActivity(const boost::property_tree::ptree& tree, const std::st
9395
return activity;
9496
}
9597

98+
std::function<validity_time_t(void)> getCcdbSorTimeAccessor(uint64_t runNumber)
99+
{
100+
return [runNumber]() { return static_cast<validity_time_t>(ccdb::BasicCCDBManager::instance().getRunDuration(runNumber, false).first); };
101+
}
102+
103+
std::function<validity_time_t(void)> getCcdbEorTimeAccessor(uint64_t runNumber)
104+
{
105+
return [runNumber]() { return static_cast<validity_time_t>(ccdb::BasicCCDBManager::instance().getRunDuration(runNumber, false).second); };
106+
}
107+
96108
} // namespace o2::quality_control::core::activity_helpers

Framework/src/TaskRunner.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "QualityControl/Bookkeeping.h"
4747
#include "QualityControl/TimekeeperSynchronous.h"
4848
#include "QualityControl/TimekeeperAsynchronous.h"
49+
#include "QualityControl/ActivityHelpers.h"
4950

5051
#include <string>
5152
#include <TFile.h>
@@ -462,9 +463,9 @@ void TaskRunner::startOfActivity()
462463
mObjectsManager->setActivity(activity);
463464

464465
auto now = getCurrentTimestamp();
465-
mTimekeeper->setStartOfActivity(activity.mValidity.getMin(), mTaskConfig.fallbackActivity.mValidity.getMin(), now);
466+
mTimekeeper->setStartOfActivity(activity.mValidity.getMin(), mTaskConfig.fallbackActivity.mValidity.getMin(), now, activity_helpers::getCcdbSorTimeAccessor(mRunNumber));
466467
mTimekeeper->updateByCurrentTimestamp(mTimekeeper->getActivityDuration().getMin());
467-
mTimekeeper->setEndOfActivity(activity.mValidity.getMax(), mTaskConfig.fallbackActivity.mValidity.getMax(), now);
468+
mTimekeeper->setEndOfActivity(activity.mValidity.getMax(), mTaskConfig.fallbackActivity.mValidity.getMax(), now, activity_helpers::getCcdbEorTimeAccessor(mRunNumber));
468469

469470
mCollector->setRunNumber(mRunNumber);
470471
mTask->startOfActivity(activity);
@@ -477,7 +478,7 @@ void TaskRunner::endOfActivity()
477478

478479
auto now = getCurrentTimestamp();
479480
mTimekeeper->updateByCurrentTimestamp(now);
480-
mTimekeeper->setEndOfActivity(0, mTaskConfig.fallbackActivity.mValidity.getMax(), now); // TODO: get end of run from ECS/BK if possible
481+
mTimekeeper->setEndOfActivity(0, mTaskConfig.fallbackActivity.mValidity.getMax(), now, activity_helpers::getCcdbEorTimeAccessor(mRunNumber)); // TODO: get end of run from ECS/BK if possible
481482

482483
mTask->endOfActivity(mObjectsManager->getActivity());
483484
mObjectsManager->removeAllFromServiceDiscovery();

Framework/src/Timekeeper.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ TimeframeIdRange Timekeeper::getTimerangeIdRange() const
4646
}
4747

4848
void Timekeeper::setStartOfActivity(validity_time_t ecsTimestamp, validity_time_t configTimestamp,
49-
validity_time_t currentTimestamp)
49+
validity_time_t currentTimestamp, std::function<validity_time_t(void)> ccdbTimestampAccessor)
5050
{
51-
mActivityDuration.setMin(activityBoundarySelectionStrategy(ecsTimestamp, configTimestamp, currentTimestamp));
51+
mActivityDuration.setMin(activityBoundarySelectionStrategy(ecsTimestamp, configTimestamp, currentTimestamp, ccdbTimestampAccessor));
5252
}
5353

5454
void Timekeeper::setEndOfActivity(validity_time_t ecsTimestamp, validity_time_t configTimestamp,
55-
validity_time_t currentTimestamp)
55+
validity_time_t currentTimestamp, std::function<validity_time_t(void)> ccdbTimestampAccessor)
5656
{
57-
mActivityDuration.setMax(activityBoundarySelectionStrategy(ecsTimestamp, configTimestamp, currentTimestamp));
57+
mActivityDuration.setMax(activityBoundarySelectionStrategy(ecsTimestamp, configTimestamp, currentTimestamp, ccdbTimestampAccessor));
5858
}
5959

6060
ValidityInterval Timekeeper::getActivityDuration() const

Framework/src/TimekeeperAsynchronous.cxx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,30 @@ void TimekeeperAsynchronous::reset()
8989
mCurrentTimeframeIdRange = gInvalidTimeframeIdRange;
9090
}
9191

92+
template <typename T>
93+
bool not_on_limit(T value)
94+
{
95+
return value != std::numeric_limits<T>::min() && value != std::numeric_limits<T>::max();
96+
}
97+
9298
validity_time_t
93-
TimekeeperAsynchronous::activityBoundarySelectionStrategy(validity_time_t ecsTimestamp, validity_time_t configTimestamp,
94-
validity_time_t currentTimestamp)
99+
TimekeeperAsynchronous::activityBoundarySelectionStrategy(validity_time_t ecsTimestamp,
100+
validity_time_t configTimestamp,
101+
validity_time_t currentTimestamp,
102+
std::function<validity_time_t(void)> ccdbTimestampAccessor)
95103
{
96-
auto notOnLimit = [](validity_time_t value) {
97-
return value != std::numeric_limits<validity_time_t>::min() && value != std::numeric_limits<validity_time_t>::max();
98-
};
99104
validity_time_t selected = 0;
100-
if (notOnLimit(ecsTimestamp)) {
105+
auto ccdbTimestamp = ccdbTimestampAccessor == nullptr ? std::numeric_limits<validity_time_t>::min() : ccdbTimestampAccessor();
106+
if (not_on_limit(ccdbTimestamp)) {
107+
selected = ccdbTimestamp;
108+
} else if (not_on_limit(ecsTimestamp)) {
101109
selected = ecsTimestamp;
102-
} else if (notOnLimit(configTimestamp)) {
110+
} else if (not_on_limit(configTimestamp)) {
103111
selected = configTimestamp;
104112
} else {
105113
// an exception could be thrown here once the values above are set correctly in production
106114
}
107-
ILOG(Info, Devel) << "Received the following activity boundary propositions: " << ecsTimestamp
115+
ILOG(Info, Devel) << "Received the following activity boundary propositions: " << ccdbTimestamp << ", " << ecsTimestamp
108116
<< ", " << configTimestamp << ", " << currentTimestamp << ". Selected: " << selected << ENDM;
109117
return selected;
110118
}

Framework/src/TimekeeperSynchronous.cxx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,22 @@ void TimekeeperSynchronous::reset()
7272
mCurrentTimeframeIdRange = gInvalidTimeframeIdRange;
7373
}
7474

75+
template <typename T>
76+
bool not_on_limit(T value)
77+
{
78+
return value != std::numeric_limits<T>::min() && value != std::numeric_limits<T>::max();
79+
}
80+
7581
validity_time_t
76-
TimekeeperSynchronous::activityBoundarySelectionStrategy(validity_time_t ecsTimestamp, validity_time_t configTimestamp,
77-
validity_time_t currentTimestamp)
82+
TimekeeperSynchronous::activityBoundarySelectionStrategy(validity_time_t ecsTimestamp,
83+
validity_time_t configTimestamp,
84+
validity_time_t currentTimestamp,
85+
std::function<validity_time_t(void)>)
7886
{
79-
auto notOnLimit = [](validity_time_t value) {
80-
return value != std::numeric_limits<validity_time_t>::min() && value != std::numeric_limits<validity_time_t>::max();
81-
};
8287
validity_time_t selected = 0;
83-
if (notOnLimit(ecsTimestamp)) {
88+
if (not_on_limit(ecsTimestamp)) {
8489
selected = ecsTimestamp;
85-
} else if (notOnLimit(currentTimestamp)) {
90+
} else if (not_on_limit(currentTimestamp)) {
8691
selected = currentTimestamp;
8792
} else {
8893
selected = configTimestamp;

Framework/test/testTimekeeper.cxx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#include "QualityControl/Timekeeper.h"
1818
#include "QualityControl/TimekeeperSynchronous.h"
1919
#include "QualityControl/TimekeeperAsynchronous.h"
20+
#include "QualityControl/ActivityHelpers.h"
2021
#include <Framework/TimingInfo.h>
22+
#include <CommonUtils/ConfigurableParam.h>
2123

2224
#include <catch_amalgamated.hpp>
2325

@@ -289,7 +291,15 @@ TEST_CASE("timekeeper_asynchronous")
289291
{
290292
auto tk = std::make_shared<TimekeeperAsynchronous>();
291293

292-
// ECS first
294+
o2::conf::ConfigurableParam::updateFromString("NameConf.mCCDBServer=http://ccdb-test.cern.ch:8080");
295+
296+
// CCDB RCT first
297+
tk->setStartOfActivity(1, 2, 3, activity_helpers::getCcdbSorTimeAccessor(300000));
298+
tk->setEndOfActivity(4, 5, 6, activity_helpers::getCcdbEorTimeAccessor(300000));
299+
CHECK(tk->getActivityDuration().getMin() > 100);
300+
CHECK(tk->getActivityDuration().getMax() > 100);
301+
302+
// ECS second
293303
tk->setStartOfActivity(1, 2, 3);
294304
tk->setEndOfActivity(4, 5, 6);
295305
CHECK(tk->getActivityDuration().getMin() == 1);

0 commit comments

Comments
 (0)