Skip to content

Commit 3c0f908

Browse files
committed
Data management event handling services at the Replication system
1 parent a78c1ea commit 3c0f908

10 files changed

Lines changed: 225 additions & 20 deletions

src/replica/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ target_link_libraries(replica PUBLIC
2323
replica_util
2424
replica_worker
2525
css
26+
cconfig
2627
xrdreq
2728
xrdsvc
2829
XrdCl

src/replica/contr/HttpIngestModule.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "boost/algorithm/string.hpp"
3636

3737
// Qserv headers
38+
#include "cconfig/DataManagementEvent.h"
3839
#include "css/CssAccess.h"
3940
#include "css/CssError.h"
4041
#include "css/DbInterfaceMySql.h"
@@ -53,7 +54,10 @@
5354
#include "replica/jobs/SqlGrantAccessJob.h"
5455
#include "replica/jobs/SqlEnableDbJob.h"
5556
#include "replica/jobs/SqlRemoveTablePartitionsJob.h"
57+
#include "replica/qserv/PostEventQservCzarMgtRequest.h"
58+
#include "replica/registry/Registry.h"
5659
#include "replica/requests/SqlResultSet.h"
60+
#include "replica/services/ChunkMap.h"
5761
#include "replica/services/DatabaseServices.h"
5862
#include "replica/services/ServiceProvider.h"
5963
#include "replica/util/ChunkedTable.h"
@@ -377,6 +381,12 @@ json HttpIngestModule::_publishDatabase() {
377381
// the Replication system.
378382
_qservSync(database, allWorkers);
379383

384+
// Notify Czars about the database publication event.
385+
cconfig::DataManagementEvent dataManagementEvent;
386+
dataManagementEvent.type = cconfig::DataManagementEvent::Type::DATABASE_PUBLISHED;
387+
dataManagementEvent.database = database.name;
388+
_notifyCzars(dataManagementEvent);
389+
380390
ControllerEvent event;
381391
event.status = "PUBLISH DATABASE";
382392
event.kvInfo.emplace_back("database", database.name);
@@ -481,6 +491,12 @@ json HttpIngestModule::_deleteDatabase() {
481491
error = reconfigureWorkers(database, allWorkers, workerReconfigTimeoutSec());
482492
if (!error.empty()) throw http::Error(__func__, error);
483493

494+
// Notify Czars about the database removal event.
495+
cconfig::DataManagementEvent dataManagementEvent;
496+
dataManagementEvent.type = cconfig::DataManagementEvent::Type::DATABASE_DELETED;
497+
dataManagementEvent.database = database.name;
498+
_notifyCzars(dataManagementEvent);
499+
484500
return json::object();
485501
}
486502

@@ -745,6 +761,13 @@ json HttpIngestModule::_deleteTable() {
745761
error = reconfigureWorkers(database, allWorkers, workerReconfigTimeoutSec());
746762
if (!error.empty()) throw http::Error(__func__, error);
747763

764+
// Notify Czars about the table removal event.
765+
cconfig::DataManagementEvent dataManagementEvent;
766+
dataManagementEvent.type = cconfig::DataManagementEvent::Type::TABLE_DELETED;
767+
dataManagementEvent.database = database.name;
768+
dataManagementEvent.table = table.name;
769+
_notifyCzars(dataManagementEvent);
770+
748771
return json::object();
749772
}
750773

@@ -1414,4 +1437,17 @@ void HttpIngestModule::_qservSync(DatabaseInfo const& database, bool allWorkers)
14141437
}
14151438
}
14161439

1440+
void HttpIngestModule::_notifyCzars(cconfig::DataManagementEvent const& dataManagementEvent) const {
1441+
// The replica disposition map neeeds to be updated in the database before sending
1442+
// the notification to the czars.
1443+
auto const serviceProvider = controller()->serviceProvider();
1444+
serviceProvider->chunkMap()->update();
1445+
auto const czars = serviceProvider->registry()->czars();
1446+
for (auto const& czar : czars) {
1447+
auto const request =
1448+
PostEventQservCzarMgtRequest::create(serviceProvider, czar.name, dataManagementEvent);
1449+
request->start();
1450+
}
1451+
}
1452+
14171453
} // namespace lsst::qserv::replica

src/replica/contr/HttpIngestModule.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#include "replica/util/Common.h"
3535

3636
// Forward declarations
37+
namespace lsst::qserv::cconfig {
38+
class DataManagementEvent;
39+
} // namespace lsst::qserv::cconfig
40+
3741
namespace lsst::qserv::replica {
3842
class DatabaseInfo;
3943
} // namespace lsst::qserv::replica
@@ -182,7 +186,6 @@ class HttpIngestModule : public HttpModule {
182186
/**
183187
* Grant SELECT authorizations for the new database to Qserv
184188
* MySQL account(s) at workers.
185-
*
186189
* @param database database descriptor
187190
* @param allWorkers 'true' if all workers should be involved into the operation
188191
* @throws http::Error if the operation failed
@@ -192,7 +195,6 @@ class HttpIngestModule : public HttpModule {
192195
/**
193196
* Enable this database in Qserv workers by adding an entry
194197
* to table 'qservw_worker.Dbs' at workers.
195-
*
196198
* @param database database descriptor
197199
* @param allWorkers 'true' if all workers should be involved into the operation
198200
* @throws http::Error if the operation failed
@@ -205,7 +207,6 @@ class HttpIngestModule : public HttpModule {
205207
* tables have chunks representations for all registered chunks, even though some
206208
* of the chunks may be empty. This stage enforces structural consistency across
207209
* partitioned tables.
208-
*
209210
* @param database database descriptor
210211
* @param allWorkers 'true' if all workers should be involved into the operation
211212
* @throws http::Error if the operation failed
@@ -214,7 +215,6 @@ class HttpIngestModule : public HttpModule {
214215

215216
/**
216217
* Consolidate MySQL partitioned tables at workers by removing partitions.
217-
*
218218
* @param database database descriptor
219219
* @param allWorkers 'true' if all workers should be involved into the operation
220220
* @throws http::Error if operation failed
@@ -235,7 +235,6 @@ class HttpIngestModule : public HttpModule {
235235
/**
236236
* (Re-)build the empty chunks list (table) for the specified database.
237237
* The methods throws exceptions in case of any errors.
238-
*
239238
* @param databaseName The name of a database.
240239
* @param force Rebuild the list if 'true'.
241240
* @return An object representing a result of the operation (empty chunk list
@@ -266,13 +265,18 @@ class HttpIngestModule : public HttpModule {
266265
* It runs the Replication system's chunks scanner to register chunk info
267266
* in the persistent state of the system. It also registers (synchronizes)
268267
* new chunks at Qserv workers.
269-
*
270268
* @param database database descriptor
271269
* @param allWorkers 'true' if all workers should be involved into the operation
272270
* @throws http::Error if the operation failed
273271
*/
274272
void _qservSync(DatabaseInfo const& database, bool allWorkers) const;
275273

274+
/**
275+
* Notify Czars about a data management event.
276+
* @param dataManagementEvent the event to be posted to Czars
277+
*/
278+
void _notifyCzars(cconfig::DataManagementEvent const& dataManagementEvent) const;
279+
276280
// The name and a type of a special column for the super-transaction-based ingest
277281

278282
static std::string const _partitionByColumn;

src/replica/contr/ReplicationTask.cc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ bool ReplicationTask::onRun() {
5656
launch<FindAllJob>(priority, saveReplicaInfo, allWorkers);
5757
if (!_disableQservSync) sync(_qservSyncTimeoutSec, _forceQservSync);
5858

59-
if (_qservChunkMapUpdate) _updateChunkMap();
59+
if (_qservChunkMapUpdate) serviceProvider()->chunkMap()->update();
6060

6161
launch<FixUpJob>(priority);
6262
if (!_disableQservSync) sync(_qservSyncTimeoutSec, _forceQservSync);
@@ -88,12 +88,4 @@ ReplicationTask::ReplicationTask(Controller::Ptr const& controller,
8888
_qservChunkMapUpdate(qservChunkMapUpdate),
8989
_purge(purge) {}
9090

91-
void ReplicationTask::_updateChunkMap() {
92-
if (!serviceProvider()->chunkMap()->update()) {
93-
error("failed to update chunk map in the Czar database");
94-
} else {
95-
info("chunk map has been updated in the Czar database");
96-
}
97-
}
98-
9991
} // namespace lsst::qserv::replica

src/replica/contr/ReplicationTask.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ class ReplicationTask : public Task {
8181
unsigned int qservSyncTimeoutSec, bool disableQservSync, bool forceQservSync,
8282
bool qservChunkMapUpdate, unsigned int replicationIntervalSec, bool purge);
8383

84-
/// Update the chunk disposition map in QMeta when changes in the map are detected.
85-
void _updateChunkMap();
86-
8784
/// The maximum number of seconds to be waited before giving up
8885
/// on the Qserv synchronization requests.
8986
unsigned int const _qservSyncTimeoutSec;

src/replica/qserv/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ target_sources(replica_qserv PRIVATE
1616
QservMgtRequest.cc
1717
QservMgtServices.cc
1818
QservWorkerMgtRequest.cc
19+
PostEventQservCzarMgtRequest.cc
1920
RemoveReplicaQservMgtRequest.cc
2021
SetReplicasQservMgtRequest.cc
2122
TestEchoQservMgtRequest.cc
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* LSST Data Management System
3+
*
4+
* This product includes software developed by the
5+
* LSST Project (http://www.lsst.org/).
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the LSST License Statement and
18+
* the GNU General Public License along with this program. If not,
19+
* see <http://www.lsstcorp.org/LegalNotices/>.
20+
*/
21+
22+
// Class header
23+
#include "replica/qserv/PostEventQservCzarMgtRequest.h"
24+
25+
// Qserv headers
26+
#include "http/Method.h"
27+
#include "replica/util/Common.h"
28+
29+
// LSST headers
30+
#include "lsst/log/Log.h"
31+
32+
using namespace nlohmann;
33+
using namespace std;
34+
35+
namespace {
36+
37+
LOG_LOGGER _log = LOG_GET("lsst.qserv.replica.PostEventQservCzarMgtRequest");
38+
39+
} // namespace
40+
41+
namespace lsst::qserv::replica {
42+
43+
PostEventQservCzarMgtRequest::Ptr PostEventQservCzarMgtRequest::create(
44+
shared_ptr<ServiceProvider> const& serviceProvider, string const& czarName,
45+
cconfig::DataManagementEvent const& event,
46+
PostEventQservCzarMgtRequest::CallbackType const& onFinish) {
47+
return PostEventQservCzarMgtRequest::Ptr(
48+
new PostEventQservCzarMgtRequest(serviceProvider, czarName, event, onFinish));
49+
}
50+
51+
PostEventQservCzarMgtRequest::PostEventQservCzarMgtRequest(
52+
shared_ptr<ServiceProvider> const& serviceProvider, string const& czarName,
53+
cconfig::DataManagementEvent const& event, PostEventQservCzarMgtRequest::CallbackType const& onFinish)
54+
: QservCzarMgtRequest(serviceProvider, "QSERV_CZAR_POST_EVENT", czarName),
55+
_event(event),
56+
_onFinish(onFinish) {}
57+
58+
list<pair<string, string>> PostEventQservCzarMgtRequest::extendedPersistentState() const {
59+
list<pair<string, string>> result;
60+
result.emplace_back("czar", czarName());
61+
return result;
62+
}
63+
64+
void PostEventQservCzarMgtRequest::createHttpReqImpl(replica::Lock const& lock) {
65+
string const target = "/event";
66+
json const data = json::object({{"czar", czarName()}, {"event", _event.toJson()}});
67+
createHttpReq(lock, http::Method::POST, target, data);
68+
}
69+
70+
void PostEventQservCzarMgtRequest::notify(replica::Lock const& lock) {
71+
LOGS(_log, LOG_LVL_TRACE, context() << __func__);
72+
notifyDefaultImpl<PostEventQservCzarMgtRequest>(lock, _onFinish);
73+
}
74+
75+
} // namespace lsst::qserv::replica
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* LSST Data Management System
3+
*
4+
* This product includes software developed by the
5+
* LSST Project (http://www.lsst.org/).
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the LSST License Statement and
18+
* the GNU General Public License along with this program. If not,
19+
* see <http://www.lsstcorp.org/LegalNotices/>.
20+
*/
21+
#ifndef LSST_QSERV_REPLICA_POSTEVENTQSERVCZARMGTREQUEST_H
22+
#define LSST_QSERV_REPLICA_POSTEVENTQSERVCZARMGTREQUEST_H
23+
24+
// System headers
25+
#include <list>
26+
#include <memory>
27+
#include <string>
28+
#include <utility>
29+
30+
// Third party headers
31+
#include "nlohmann/json.hpp"
32+
33+
// Qserv headers
34+
#include "cconfig/DataManagementEvent.h"
35+
#include "replica/qserv/QservCzarMgtRequest.h"
36+
37+
namespace lsst::qserv::replica {
38+
class ServiceProvider;
39+
} // namespace lsst::qserv::replica
40+
41+
// This header declarations
42+
namespace lsst::qserv::replica {
43+
44+
/**
45+
* Class PostEventQservCzarMgtRequest implements a request for posting the data
46+
* management events to the Qserv Czar.
47+
*/
48+
class PostEventQservCzarMgtRequest : public QservCzarMgtRequest {
49+
public:
50+
typedef std::shared_ptr<PostEventQservCzarMgtRequest> Ptr;
51+
52+
/// The function type for notifications on the completion of the request
53+
typedef std::function<void(Ptr)> CallbackType;
54+
55+
PostEventQservCzarMgtRequest() = delete;
56+
PostEventQservCzarMgtRequest(PostEventQservCzarMgtRequest const&) = delete;
57+
PostEventQservCzarMgtRequest& operator=(PostEventQservCzarMgtRequest const&) = delete;
58+
59+
virtual ~PostEventQservCzarMgtRequest() override = default;
60+
61+
/**
62+
* Static factory method is needed to prevent issues with the lifespan
63+
* and memory management of instances created otherwise (as values or via
64+
* low-level pointers).
65+
*
66+
* @param serviceProvider A reference to a provider of services for accessing
67+
* Configuration, saving the request's persistent state to the database.
68+
* @param czarName The name of a Czar to send the request to.
69+
* @param event The management event to be posted to the Czar.
70+
* @param onFinish (optional) callback function to be called upon request completion.
71+
* @return A pointer to the created object.
72+
*/
73+
static Ptr create(ServiceProvider::Ptr const& serviceProvider, std::string const& czarName,
74+
cconfig::DataManagementEvent const& event, CallbackType const& onFinish = nullptr);
75+
76+
/// @see QservMgtRequest::extendedPersistentState()
77+
std::list<std::pair<std::string, std::string>> extendedPersistentState() const override;
78+
79+
protected:
80+
/// @see QservMgtRequest::createHttpReqImpl()
81+
virtual void createHttpReqImpl(replica::Lock const& lock) override;
82+
83+
/// @see QservMgtRequest::notify
84+
virtual void notify(replica::Lock const& lock) override;
85+
86+
private:
87+
/// @see PostEventQservCzarMgtRequest::create()
88+
PostEventQservCzarMgtRequest(ServiceProvider::Ptr const& serviceProvider, std::string const& czarName,
89+
cconfig::DataManagementEvent const& event, CallbackType const& onFinish);
90+
91+
// Input parameters
92+
93+
cconfig::DataManagementEvent const _event; ///< The management event to be posted to the Czar.
94+
CallbackType _onFinish; ///< The callback function is reset when the request finishes.
95+
};
96+
97+
} // namespace lsst::qserv::replica
98+
99+
#endif // LSST_QSERV_REPLICA_POSTEVENTQSERVCZARMGTREQUEST_H

src/replica/services/ChunkMap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class ChunkMap : public std::enable_shared_from_this<ChunkMap> {
9595

9696
// The internal representation of the current state of the chunk map.
9797

98-
std::shared_ptr<Chunks> _chunks; ///< The the current state.
98+
std::shared_ptr<Chunks> _chunks; ///< The current state.
9999
mutable std::mutex _mtx; ///< Mutex to protect access to the chunk map.
100100
};
101101

src/replica/services/ServiceProvider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@
3333
// Qserv headers
3434
#include "http/Auth.h"
3535
#include "replica/services/ChunkLocker.h"
36-
#include "replica/services/ChunkMap.h"
3736
#include "replica/util/Mutex.h"
3837
#include "replica/util/NamedMutexRegistry.h"
3938

4039
// Forward declarations
4140
namespace lsst::qserv::replica {
41+
class ChunkMap;
4242
class Configuration;
4343
class DatabaseServices;
4444
class Messenger;

0 commit comments

Comments
 (0)