Leosac  0.8.0
Open Source Access Control
ReplicationModule.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "ReplicationModule.hpp"
21 #include "core/CoreUtils.hpp"
22 #include "core/Scheduler.hpp"
27 #include "tools/log.hpp"
28 
29 using namespace Leosac::Module::Replication;
30 
31 ReplicationModule::ReplicationModule(zmqpp::context &ctx, zmqpp::socket *pipe,
32  const boost::property_tree::ptree &cfg,
33  CoreUtilsPtr utils)
34  : BaseModule(ctx, pipe, cfg, utils)
35  , last_sync_(TimePoint::max())
36 {
38 }
39 
41 {
42  while (is_running_)
43  {
44  auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
45  std::chrono::system_clock::now() - last_sync_)
46  .count();
47  if (last_sync_ == TimePoint::max() || elapsed > delay_)
48  {
49  replicate();
50  last_sync_ = std::chrono::system_clock::now();
51  }
52  reactor_.poll(25);
53  }
54 }
55 
57 {
58  delay_ = config_.get_child("module_config").get<int>("delay", 120);
59  endpoint_ = config_.get_child("module_config").get<std::string>("endpoint");
60  pubkey_ = config_.get_child("module_config").get<std::string>("pubkey");
61 }
62 
64 {
65  uint64_t local;
66  uint64_t remote;
67  bool ok = true;
68 
69  ok &= fetch_local_version(local);
70  ok &= fetch_remote_version(remote);
71 
72  if (ok)
73  INFO("Current cfg version = " << local << ". Remote = " << remote);
74  else
75  {
76  ERROR("Failed to retrieve config version");
77  return;
78  }
79 
80  if (remote > local)
81  {
82  start_sync();
83  }
84  else
85  {
86  INFO("Local configuration version is either equal or greated than the "
87  "remote's."
88  << " Doing nothing.");
89  }
90 }
91 
93 {
94  auto task = std::make_shared<Tasks::GetLocalConfigVersion>(utils_->kernel());
95  utils_->scheduler().enqueue(task, TargetThread::MAIN);
96  task->wait();
97  assert(task->succeed());
98 
99  local = task->config_version_;
100  return true;
101 }
102 
104 {
105  auto task = std::make_shared<Tasks::GetRemoteConfigVersion>(endpoint_, pubkey_);
106  utils_->scheduler().enqueue(task, TargetThread::POOL);
107  task->wait();
108 
109  if (!task->succeed())
110  {
111  if (task->get_exception())
112  {
113  try
114  {
115  std::rethrow_exception(task->get_exception());
116  }
117  catch (const std::exception &e)
118  {
119  ERROR("Fetching remote version failed: " << e.what());
120  return false;
121  }
122  }
123  return false;
124  }
125  remote = task->config_version_;
126  return true;
127 }
128 
130 {
131  INFO("Starting the synchronization process...");
132  // two tasks queued. Fetch and Sync.
133 
134  auto fetch_task = std::make_shared<Tasks::FetchRemoteConfig>(endpoint_, pubkey_);
135 
136  auto sync_task = std::make_shared<Tasks::SyncConfig>(utils_->kernel(),
137  fetch_task, true, true);
138  sync_task->set_on_success([]() { INFO("Synchronization complete."); });
139 
140  auto *sched = &utils_->scheduler();
141  fetch_task->set_on_success(
142  [=]() { sched->enqueue(sync_task, TargetThread::MAIN); });
143  utils_->scheduler().enqueue(fetch_task, TargetThread::POOL);
144 }
Leosac::Module::Replication::ReplicationModule::process_config
void process_config()
Definition: ReplicationModule.cpp:56
Leosac::Module::Replication::ReplicationModule::pubkey_
std::string pubkey_
Master server's public key.
Definition: ReplicationModule.hpp:95
Leosac::Module::Replication::ReplicationModule::start_sync
void start_sync()
Launch the tasks so that the synchronisation may take place.
Definition: ReplicationModule.cpp:129
Leosac::Module::BaseModule
Base class for module implementation.
Definition: BaseModule.hpp:110
SyncConfig.hpp
ERROR
@ ERROR
Definition: log.hpp:32
Leosac::Module::Replication::ReplicationModule::replicate
void replicate()
Start the replication process.
Definition: ReplicationModule.cpp:63
INFO
@ INFO
Definition: log.hpp:34
GetRemoteConfigVersion.hpp
Scheduler.hpp
Leosac::Module::Replication::ReplicationModule::ReplicationModule
ReplicationModule(zmqpp::context &ctx, zmqpp::socket *pipe, const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
Definition: ReplicationModule.cpp:31
GetLocalConfigVersion.hpp
Leosac::Module::BaseModule::config_
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
Leosac::Module::BaseModule::reactor_
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
Leosac::Module::BaseModule::utils_
CoreUtilsPtr utils_
Pointer to the core utils, which gives access to scheduler and others.
Definition: BaseModule.hpp:198
Leosac::Module::Replication::ReplicationModule::fetch_local_version
bool fetch_local_version(uint64_t &local)
Fetch the local configuration version by running a task in the main thread.
Definition: ReplicationModule.cpp:92
Leosac::Module::Replication::ReplicationModule::TimePoint
std::chrono::system_clock::time_point TimePoint
Definition: ReplicationModule.hpp:54
Leosac::Module::BaseModule::is_running_
bool is_running_
Boolean indicating whether the main loop should run or not.
Definition: BaseModule.hpp:203
Leosac::Module::Replication::ReplicationModule::delay_
int delay_
Delay between 2 replications attempt.
Definition: ReplicationModule.hpp:85
FetchRemoteConfig.hpp
Leosac::TargetThread::MAIN
@ MAIN
Leosac::Module::Replication::ReplicationModule::last_sync_
TimePoint last_sync_
Definition: ReplicationModule.hpp:97
Leosac::Module::Replication
This module handles the master/slave replication process, from the slave point of view.
Definition: ReplicationModule.hpp:35
log.hpp
CoreUtils.hpp
Leosac::Module::Replication::ReplicationModule::endpoint_
std::string endpoint_
Target master server.
Definition: ReplicationModule.hpp:90
Leosac::Module::Replication::ReplicationModule::run
virtual void run() override
This is the main loop of the module.
Definition: ReplicationModule.cpp:40
ReplicationModule.hpp
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
Leosac::Module::Replication::ReplicationModule::fetch_remote_version
bool fetch_remote_version(uint64_t &remote)
Fetch the remote configuration version by running a task in a pool, and sending the CONFIG_VERSION me...
Definition: ReplicationModule.cpp:103
Leosac::TargetThread::POOL
@ POOL