Working on legislator interfaces

This commit is contained in:
Julien CLEMENT 2020-05-05 19:29:14 +02:00
parent b6c825a877
commit fd4de7091c
15 changed files with 226 additions and 7 deletions

@ -74,7 +74,8 @@ EVENTS = \
LEGISLATOR = \ LEGISLATOR = \
src/legislator/legislator.cc \ src/legislator/legislator.cc \
src/legislator/legislator-factory.cc src/legislator/legislator-factory.cc \
src/legislator/ledger.cc
SOCKET = \ SOCKET = \
src/socket/default-socket.cc \ src/socket/default-socket.cc \

@ -3,7 +3,7 @@
{ {
"ip" : "127.0.0.1", "ip" : "127.0.0.1",
"port" : 8000, "port" : 8000,
"name" : "test", "name" : "legislator1",
"self" : true "self" : true
} }
] ]

0
src/law/ballot.cc Normal file

15
src/law/ballot.hh Normal file

@ -0,0 +1,15 @@
#pragma once
#include <unordered_set>
#include "decree.hh"
namespace paxos
{
struct Ballot
{
int id;
Decree decree;
std::unordered_set<std::string> quorum;
std::unordered_set<std::string> voters;
}
}

0
src/law/decree.cc Normal file

9
src/law/decree.hh Normal file

@ -0,0 +1,9 @@
#pragma once
namespace paxos
{
struct Decree
{
int decree;
};
}

65
src/legislator/ledger.cc Normal file

@ -0,0 +1,65 @@
#include "ledger.hh"
#include <fstream>
#include <filesystem>
namespace paxos
{
Ledger::Ledger(std::string path)
: base_path_(path)
{
std::filesystem::create_directory(path);
base_path_ += "/";
}
std::vector<Decree> Ledger::get_decrees()
{
return std::vector<Decree>();
}
int Ledger::last_tried()
{
return read_file(base_path_ + "last-tried.txt");
}
void Ledger::set_last_tried(int b)
{
write_file(base_path_ + "last-tried.txt", b);
}
int Ledger::prev_vote()
{
return read_file(base_path_ + "prev-vote.txt");
}
void Ledger::set_prev_vote(int v)
{
write_file(base_path_ + "prev-vote.txt", v);
}
int Ledger::next_bal()
{
return read_file(base_path_ + "next-bal.txt");
}
void Ledger::set_next_bal(int b)
{
write_file(base_path_ + "next-bal.txt", b);
}
int Ledger::read_file(std::string path)
{
std::ifstream stream(path);
if (!stream.good())
return -1;
int res;
stream >> res;
return res;
}
void Ledger::write_file(std::string path, int n)
{
std::ofstream stream(path);
stream << n;
}
}

31
src/legislator/ledger.hh Normal file

@ -0,0 +1,31 @@
#pragma once
#include <string>
#include <vector>
#include "law/decree.hh"
namespace paxos
{
class Ledger
{
public:
Ledger(std::string path);
std::vector<Decree> get_decrees();
int last_tried();
void set_last_tried(int b);
int prev_vote();
void set_prev_vote(int v);
int next_bal();
void set_next_bal(int b);
private:
std::string base_path_;
int read_file(std::string path);
void write_file(std::string path, int n);
};
}

@ -1,9 +1,63 @@
#include "legislator.hh" #include "legislator.hh"
#include "misc/logger.hh"
#include <string>
namespace paxos namespace paxos
{ {
Legislator::Legislator(const LegislatorConfig& config) Legislator::Legislator(const LegislatorConfig& config)
: config_(config) : config_(config), ledger(config.name)
{ {
log("created legislator " + config.name, blue);
}
void Legislator::initiate_ballot()
{
int new_ballot_number = ledger.last_tried() + 1;
ledger.set_last_tried(new_ballot_number);
log(config_.name + " is initiating ballot " + std::to_string(new_ballot_number), cyan);
send_next_ballot(new_ballot_number);
}
void Legislator::send_next_ballot(int ballot)
{
ballot = ballot;
return;
}
void Legislator::receive_next_ballot(int ballot, std::string sender)
{
log(config_.name + " has received a NextBallot("
+ std::to_string(ballot)
+ ") from " + sender, cyan);
int next_ballot = ledger.next_bal();
if (ballot <= next_ballot)
{
log("but it was discarded because ballot " + std::to_string(ballot)
+ " is inferior or equal to nextBallot "
+ std::to_string(next_ballot), red);
return;
}
ledger.set_next_bal(ballot);
int previous_vote = ledger.prev_vote();
previous_vote = previous_vote;
//XXX send a LastVote to sender
}
void Legislator::receive_enough_last_vote
(std::unordered_map<std::string, int> quorum_last_votes)
{
quorum_last_votes = quorum_last_votes;
//find d to satisfy B3
//send BeginBallot to the quorum
}
void Legislator::receive_begin_ballot(int ballot, int decree)
{
if (ballot != ledger.next_bal())
return;
ledger.set_prev_vote(ballot);
decree = decree;
//XXX send Voted
} }
} }

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "config/config.hh" #include "config/config.hh"
#include "ledger.hh"
#include <unordered_map>
namespace paxos namespace paxos
{ {
@ -9,6 +11,21 @@ namespace paxos
Legislator(const LegislatorConfig& config); Legislator(const LegislatorConfig& config);
LegislatorConfig config_; LegislatorConfig config_;
void initiate_ballot();
void send_next_ballot(int ballot);
void receive_next_ballot(int ballot, std::string sender);
void receive_enough_last_vote
(std::unordered_map<std::string, int> quorum_last_votes);
void receive_begin_ballot(int ballot, int decree);
Ledger ledger;
}; };
using shared_legislator = std::shared_ptr<Legislator>; using shared_legislator = std::shared_ptr<Legislator>;
extern shared_legislator self;
extern std::vector<shared_legislator> legislators;
} }

0
src/legislator/vote.cc Normal file

13
src/legislator/vote.hh Normal file

@ -0,0 +1,13 @@
#pragma once
#include "legislator.hh"
#include "law/decree.hh"
namespace paxos
{
struct Vote
{
Legislator legislator;
int ballot_id;
Decree decree;
};
}

@ -1,10 +1,14 @@
#include <iostream> #include <iostream>
#include <vector>
#include "config/config.hh" #include "config/config.hh"
#include "legislator/legislator-factory.hh" #include "legislator/legislator-factory.hh"
#include "events/register.hh" #include "events/register.hh"
#include "misc/logger.hh"
paxos::EventWatcherRegistry paxos::event_register; paxos::EventWatcherRegistry paxos::event_register;
std::vector<paxos::shared_legislator> paxos::legislators;
paxos::shared_legislator paxos::self;
ev_signal sigint_watcher; ev_signal sigint_watcher;
static void sigint_cb(struct ev_loop* loop, ev_signal*, int) static void sigint_cb(struct ev_loop* loop, ev_signal*, int)
@ -12,6 +16,13 @@ static void sigint_cb(struct ev_loop* loop, ev_signal*, int)
ev_break(loop, EVBREAK_ALL); ev_break(loop, EVBREAK_ALL);
} }
ev_signal sigstop_watcher;
static void sigstop_cb(struct ev_loop*, ev_signal*, int)
{
log("SIGSTOP detected trying to initiate ballot", paxos::red);
paxos::self->initiate_ballot();
}
int main(int, char **argv) int main(int, char **argv)
{ {
@ -20,11 +31,14 @@ int main(int, char **argv)
ev_signal_init(&sigint_watcher, sigint_cb, SIGINT); ev_signal_init(&sigint_watcher, sigint_cb, SIGINT);
paxos::event_register.get_event_loop().register_sigint_watcher(&sigint_watcher); paxos::event_register.get_event_loop().register_sigint_watcher(&sigint_watcher);
paxos::LegislatorFactory::Create(server_config.self_); ev_signal_init(&sigstop_watcher, sigstop_cb, SIGTSTP);
paxos::event_register.get_event_loop().register_sigint_watcher(&sigstop_watcher);
paxos::self = paxos::LegislatorFactory::Create(server_config.self_);
for (auto config : server_config.legislators_) for (auto config : server_config.legislators_)
{ {
paxos::LegislatorFactory::Create(config); paxos::legislators.push_back(paxos::LegislatorFactory::Create(config));
} }
paxos::event_register.get_event_loop()(); paxos::event_register.get_event_loop()();

@ -2,7 +2,7 @@
#include <iostream> #include <iostream>
namespace http namespace paxos
{ {
void log(std::string str, Color color) void log(std::string str, Color color)
{ {

@ -2,7 +2,7 @@
#include <string> #include <string>
namespace http namespace paxos
{ {
enum Color enum Color
{ {