Skip to content

Commit 8ec966c

Browse files
committed
Add support for the publication of the list of all published objects.
This is needed by the CCDB backend as we have no ways of asking for the list of objects. It introduces the (first) so-called system object, i.e. an object that is transmitted by tasks behind the scene the same way the explicit MonitorObjects are. At the moment, the list of objects is a comma separated list of names. It is interpreted by the CCDB backend to provide the list of published objects. (QC-53)
1 parent 19bd6ea commit 8ec966c

10 files changed

Lines changed: 622 additions & 64 deletions

File tree

Framework/include/QualityControl/MonitorObject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ class MonitorObject : public TObject
140140
return clone;
141141
}
142142

143+
// Names of special objects published by the framework for each task, behind the scene.
144+
public:
145+
static constexpr char SYSTEM_OBJECT_PUBLICATION_LIST[] = "objectsList"; // list of objects published by the task
146+
143147
private:
144148
std::string mName;
145149
Quality mQuality;

Framework/include/QualityControl/ObjectsManager.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "QualityControl/Quality.h"
1212
#include "QualityControl/MonitorObject.h"
1313
#include "QualityControl/TaskConfig.h"
14+
#include <TObjString.h>
1415

1516
namespace o2 {
1617
namespace quality_control {
@@ -27,9 +28,6 @@ class ObjectsManager
2728
friend class TaskControl; // TaskControl must be able to call "publish()" whenever needed. Nobody else can.
2829

2930
public:
30-
/// Default constructor
31-
ObjectsManager();
32-
3331
ObjectsManager(TaskConfig &taskConfig);
3432

3533
/// Destructor
@@ -38,6 +36,7 @@ class ObjectsManager
3836
void startPublishing(TObject *obj, std::string objectName = "");
3937

4038
void setQuality(std::string objectName, Quality quality);
39+
// todo stop publishing
4140

4241
Quality getQuality(std::string objectName);
4342

@@ -72,9 +71,15 @@ class ObjectsManager
7271
iterator end()
7372
{ return mMonitorObjects.end(); }
7473

74+
private:
75+
void UpdateIndex(const std::string &nonEmptyName) ;
76+
7577
private:
7678
std::map<std::string /*object name*/, quality_control::core::MonitorObject * /* object */> mMonitorObjects;
7779
std::string mTaskName;
80+
// todo make it a vector of string when support added
81+
TObjString mObjectsList; // the list of objects we publish. (comma separated)
82+
// Possibly needed on the client side to know what was there at a given time.
7883
};
7984

8085
} // namespace core

Framework/src/CcdbDatabase.cxx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
//
44

55
#include <TMessage.h>
6+
#include <TObjString.h>
67
#include "QualityControl/CcdbDatabase.h"
8+
#include <regex>
9+
#include <boost/algorithm/string/split.hpp>
10+
#include <boost/algorithm/string.hpp>
711

812
namespace o2 {
913
namespace quality_control {
@@ -253,13 +257,27 @@ void CcdbDatabase::prepareTaskDataContainer(std::string taskName)
253257

254258
std::vector<std::string> CcdbDatabase::getListOfTasksWithPublications()
255259
{
256-
std::vector<string> result{"daqTask"};
260+
std::vector<string> result{"daqTask"}; // TODO we need the "ls" feature in CCDB to list the top level nodes.
257261
return result;
258262
}
259263

260264
std::vector<std::string> CcdbDatabase::getPublishedObjectNames(std::string taskName)
261265
{
262-
std::vector<string> result{"IDs", "numberSubBlocks", "payloadSize", "PayloadSizeSubBlocks"};
266+
std::vector<string> result;
267+
// we use the "index" string to know what objects are published.
268+
// get the information from the CCDB itself.
269+
core::MonitorObject *mo = retrieve(taskName, core::MonitorObject::SYSTEM_OBJECT_PUBLICATION_LIST);
270+
auto *indexString = dynamic_cast<TObjString *>(mo->getObject());
271+
if (indexString) {
272+
string s = indexString->GetString().Data();
273+
boost::algorithm::split(result, s, boost::algorithm::is_any_of(","),boost::algorithm::token_compress_on);
274+
// sanitize : remove system objects object and empty objects
275+
result.erase(std::remove(result.begin(), result.end(), ""));
276+
result.erase(std::remove(result.begin(), result.end(), core::MonitorObject::SYSTEM_OBJECT_PUBLICATION_LIST));
277+
} else {
278+
cerr << "ok we should do something here. The 'index' object must be a TObjString" << endl;
279+
}
280+
263281
return result;
264282
}
265283

Framework/src/MonitorObject.cxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace o2 {
1111
namespace quality_control {
1212
namespace core {
1313

14+
constexpr char MonitorObject::SYSTEM_OBJECT_PUBLICATION_LIST[];
15+
1416
MonitorObject::MonitorObject()
1517
: TObject(), mName(""), mQuality(Quality::Null), mObject(nullptr), mTaskName(""), mIsOwner(true)
1618
{

Framework/src/MySqlDatabase.cxx

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace quality_control {
2525
namespace repository {
2626

2727
MySqlDatabase::MySqlDatabase()
28-
: mServer(nullptr), queueSize(0)
28+
: mServer(nullptr), queueSize(0)
2929
{
3030
lastStorage.reset();
3131
}
@@ -51,8 +51,8 @@ void MySqlDatabase::connect(std::string host, std::string database, std::string
5151
mServer = new TMySQLServer(connectionString.str().c_str(), username.c_str(), password.c_str());
5252
if (!mServer || mServer->GetErrorCode()) {
5353
string s = "Failed to connect to the database\n";
54-
if(mServer->GetErrorCode()) {
55-
s+= mServer->GetErrorMsg();
54+
if (mServer->GetErrorCode()) {
55+
s += mServer->GetErrorMsg();
5656
}
5757
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(s));
5858
} else {
@@ -65,31 +65,32 @@ void MySqlDatabase::prepareTaskDataContainer(std::string taskName)
6565
// one object per run
6666
string query;
6767
query += "CREATE TABLE IF NOT EXISTS `data_" + taskName
68-
+ "` (object_name CHAR(64), updatetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, data LONGBLOB, size INT, run INT, "
69-
"fill INT, PRIMARY KEY(object_name, run)) ENGINE=MyISAM";
68+
+
69+
"` (object_name CHAR(64), updatetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, data LONGBLOB, size INT, run INT, "
70+
"fill INT, PRIMARY KEY(object_name, run)) ENGINE=MyISAM";
7071
if (!execute(query)) {
7172
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details("Failed to create data table"));
7273
} else {
7374
QcInfoLogger::GetInstance() << "Create data table for task " << taskName << infologger::endm;
7475
}
7576
}
7677

77-
void MySqlDatabase::store(MonitorObject* mo)
78+
void MySqlDatabase::store(MonitorObject *mo)
7879
{
7980
// TODO we take ownership here to delete later -> clearly to be improved
8081
// we execute grouped insertions. Here we just register that we should keep this mo in memory.
8182
mObjectsQueue[mo->getTaskName()].push_back(mo);
8283
queueSize++;
83-
if(queueSize > 100 || lastStorage.getTime() > 10 /*sec*/) { // TODO use a configuration to set the max limits
84+
if (queueSize > 1 || lastStorage.getTime() > 10 /*sec*/) { // TODO use a configuration to set the max limits
8485
storeQueue();
8586
}
8687
}
8788

8889
void MySqlDatabase::storeQueue()
8990
{
90-
cout << "Database queue will now be processed ("<< queueSize << " objects)" << endl;
91+
cout << "Database queue will now be processed (" << queueSize << " objects)" << endl;
9192

92-
for (auto& kv : mObjectsQueue) {
93+
for (auto &kv : mObjectsQueue) {
9394
storeForTask(kv.first);
9495
}
9596
mObjectsQueue.clear();
@@ -99,9 +100,9 @@ void MySqlDatabase::storeQueue()
99100

100101
void MySqlDatabase::storeForTask(std::string taskName)
101102
{
102-
vector<MonitorObject*> objects = mObjectsQueue[taskName];
103+
vector<MonitorObject *> objects = mObjectsQueue[taskName];
103104

104-
if(objects.size() == 0) {
105+
if (objects.size() == 0) {
105106
return;
106107
}
107108

@@ -111,13 +112,7 @@ void MySqlDatabase::storeForTask(std::string taskName)
111112
// build statement string
112113
string query;
113114
query += "REPlACE INTO `data_" + taskName
114-
+ "` (object_name, data, size, run, fill) values ";
115-
for(size_t i = 0 ; i < objects.size() ; i++) {
116-
if(i != 0) {
117-
query += ",";
118-
}
119-
query += "(?,?,octet_length(data),?,?)";
120-
}
115+
+ "` (object_name, data, size, run, fill) values (?,?,octet_length(data),?,?)";
121116

122117
// Prepare statement
123118
TMySQLStatement *statement;
@@ -135,67 +130,68 @@ void MySqlDatabase::storeForTask(std::string taskName)
135130
}
136131

137132
// Assign data
138-
int i=0;
133+
// int i = 0;
139134
TMessage message(kMESS_OBJECT);
140-
for(auto mo : objects) {
135+
for (auto mo : objects) {
141136
message.Reset();
142137
message.WriteObjectAny(mo, mo->IsA());
143138
statement->NextIteration();
144-
statement->SetString(i+0, mo->getName().c_str());
145-
statement->SetBinary(i+1, message.Buffer(), message.Length(), message.Length());
146-
statement->SetInt(i+2, 0);
147-
statement->SetInt(i+3, 0);
139+
statement->SetString(0, mo->getName().c_str());
140+
statement->SetBinary(1, message.Buffer(), message.Length(), message.Length());
141+
statement->SetInt(2, 0);
142+
statement->SetInt(3, 0);
148143
}
149144
statement->Process();
150145
delete statement;
151146

152-
for(auto mo : objects) {
147+
for (auto mo : objects) {
153148
delete mo;
154149
}
155150
objects.clear();
156151
}
157152

158-
o2::quality_control::core::MonitorObject* MySqlDatabase::retrieve(std::string taskName, std::string objectName)
153+
o2::quality_control::core::MonitorObject *MySqlDatabase::retrieve(std::string taskName, std::string objectName)
159154
{
160155
string query;
161156
TMySQLStatement *statement = nullptr;
162157

163158
query += "SELECT object_name, data, updatetime, run, fill FROM data_" + taskName + " WHERE object_name = ?";
164-
statement = (TMySQLStatement*) mServer->Statement(query.c_str());
159+
statement = (TMySQLStatement *) mServer->Statement(query.c_str());
165160
if (mServer->IsError()) {
166-
if (statement)
161+
if (statement) {
167162
delete statement;
163+
}
168164
BOOST_THROW_EXCEPTION(
169-
DatabaseException() << errinfo_details("Encountered an error when creating statement in MySqlDatabase")
170-
<< errinfo_db_message(mServer->GetErrorMsg()) << errinfo_db_errno(mServer->GetErrorCode()));
165+
DatabaseException() << errinfo_details("Encountered an error when creating statement in MySqlDatabase")
166+
<< errinfo_db_message(mServer->GetErrorMsg()) << errinfo_db_errno(mServer->GetErrorCode()));
171167
}
172168
statement->NextIteration();
173169
statement->SetString(0, objectName.c_str());
174170

175171
if (!(statement->Process() && statement->StoreResult())) {
176172
delete statement;
177173
BOOST_THROW_EXCEPTION(
178-
DatabaseException()
179-
<< errinfo_details("Encountered an error when processing and storing results in MySqlDatabase")
180-
<< errinfo_db_message(mServer->GetErrorMsg()) << errinfo_db_errno(mServer->GetErrorCode()));
174+
DatabaseException()
175+
<< errinfo_details("Encountered an error when processing and storing results in MySqlDatabase")
176+
<< errinfo_db_message(mServer->GetErrorMsg()) << errinfo_db_errno(mServer->GetErrorCode()));
181177
}
182178

183-
o2::quality_control::core::MonitorObject* mo = nullptr;
179+
o2::quality_control::core::MonitorObject *mo = nullptr;
184180
if (statement->NextResultRow()) { // Consider only the first result
185181
string name = statement->GetString(0);
186-
void* blob = nullptr;
182+
void *blob = nullptr;
187183
Long_t blobSize;
188184
statement->GetBinary(1, blob, blobSize); // retrieve the data
189185
TDatime updatetime(statement->GetYear(2), statement->GetMonth(2), statement->GetDay(2), statement->GetHour(2),
190-
statement->GetMinute(2), statement->GetSecond(2));
186+
statement->GetMinute(2), statement->GetSecond(2));
191187
int run = statement->IsNull(3) ? -1 : statement->GetInt(3);
192188
int fill = statement->IsNull(4) ? -1 : statement->GetInt(4);
193189

194190
TMessage mess(kMESS_OBJECT);
195191
mess.SetBuffer(blob, blobSize, kFALSE);
196192
mess.SetReadMode();
197193
mess.Reset();
198-
mo = (o2::quality_control::core::MonitorObject*) (mess.ReadObjectAny(mess.GetClass()));
194+
mo = (o2::quality_control::core::MonitorObject *) (mess.ReadObjectAny(mess.GetClass()));
199195
}
200196
delete statement;
201197

@@ -215,19 +211,20 @@ void MySqlDatabase::disconnect()
215211
}
216212
}
217213

218-
TMySQLResult* MySqlDatabase::query(string sql)
214+
TMySQLResult *MySqlDatabase::query(string sql)
219215
{
220216
if (mServer) {
221-
return ((TMySQLResult*) mServer->Query(sql.c_str()));
217+
return ((TMySQLResult *) mServer->Query(sql.c_str()));
222218
} else {
223219
return (nullptr);
224220
}
225221
}
226222

227223
bool MySqlDatabase::execute(string sql)
228224
{
229-
if (mServer)
225+
if (mServer) {
230226
return mServer->Exec(sql.c_str());
227+
}
231228

232229
return false;
233230
}
@@ -236,7 +233,7 @@ void MySqlDatabase::addIndex(string table, string column)
236233
{
237234
std::ostringstream stringStream;
238235
stringStream << "CREATE INDEX " << table << "_i_" << column << " on " << table << " (" << column << ")";
239-
TMySQLResult* res = query(stringStream.str().c_str());
236+
TMySQLResult *res = query(stringStream.str().c_str());
240237
if (res) {
241238
delete (res);
242239
} else {
@@ -249,12 +246,12 @@ std::vector<std::string> MySqlDatabase::getPublishedObjectNames(std::string task
249246
std::vector<std::string> result;
250247

251248
string queryString = "select distinct object_name from ";
252-
queryString += taskName;
249+
queryString += "data_" + taskName;
253250

254-
TMySQLResult* mysqlResult = query(queryString);
251+
TMySQLResult *mysqlResult = query(queryString);
255252
if (mysqlResult) { // only if we got a result
256-
TMySQLRow* row;
257-
while ((row = (TMySQLRow*) mysqlResult->Next())) {
253+
TMySQLRow *row;
254+
while ((row = (TMySQLRow *) mysqlResult->Next())) {
258255
result.push_back(row->GetField(0));
259256
delete row;
260257
}
@@ -263,16 +260,17 @@ std::vector<std::string> MySqlDatabase::getPublishedObjectNames(std::string task
263260

264261
return result;
265262
}
263+
266264
std::vector<std::string> MySqlDatabase::getListOfTasksWithPublications()
267265
{
268266
std::vector<std::string> result;
269267

270268
string queryString = "select table_name from information_schema.tables where table_schema='quality_control'";
271269

272-
TMySQLResult* mysqlResult = query(queryString);
270+
TMySQLResult *mysqlResult = query(queryString);
273271
if (mysqlResult) { // only if we got a result
274-
TMySQLRow* row;
275-
while ((row = (TMySQLRow*) mysqlResult->Next())) {
272+
TMySQLRow *row;
273+
while ((row = (TMySQLRow *) mysqlResult->Next())) {
276274
result.push_back(row->GetField(0));
277275
delete row;
278276
}

Framework/src/ObjectsManager.cxx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@
99

1010
using namespace o2::quality_control::core;
1111
using namespace AliceO2::Common;
12+
using namespace std;
1213

1314
namespace o2 {
1415
namespace quality_control {
1516
namespace core {
1617

17-
ObjectsManager::ObjectsManager() : mTaskName("anonymous task")
18-
{
19-
}
20-
2118
ObjectsManager::ObjectsManager(TaskConfig &taskConfig) : mTaskName(taskConfig.taskName)
2219
{
20+
startPublishing(&mObjectsList, MonitorObject::SYSTEM_OBJECT_PUBLICATION_LIST);
2321
}
2422

2523
ObjectsManager::~ObjectsManager()
@@ -36,6 +34,17 @@ void ObjectsManager::startPublishing(TObject *object, std::string objectName)
3634
auto *newObject = new MonitorObject(nonEmptyName, object, mTaskName);
3735
newObject->setIsOwner(false);
3836
mMonitorObjects[nonEmptyName] = newObject;
37+
38+
//update index
39+
UpdateIndex(nonEmptyName);
40+
}
41+
42+
void ObjectsManager::UpdateIndex(const string &nonEmptyName)
43+
{
44+
string newString = this->mObjectsList.GetString().Data();
45+
newString += nonEmptyName;
46+
newString += ",";
47+
this->mObjectsList.SetString(newString.c_str());
3948
}
4049

4150
void ObjectsManager::setQuality(std::string objectName, Quality quality)

Framework/src/SpyMainFrame.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ bool SpyMainFrame::dbIsSelected()
297297
void SpyMainFrame::dbRun()
298298
{
299299
// Get list of objects
300-
string s = "data_";
301-
s += mTaskField->GetText();
300+
// string s = "data_";
301+
string s = mTaskField->GetText();
302302
vector<string> objectNames = mDbInterface->getPublishedObjectNames(s);
303303

304304
// UpdateList for each

0 commit comments

Comments
 (0)