Skip to content

Commit

Permalink
elector: move all the elector callouts into the Elector
Browse files Browse the repository at this point in the history
In the next commit we'll actually use the ElectionOwner interface.

Signed-off-by: Greg Farnum <gfarnum@redhat.com>
  • Loading branch information
gregsfortytwo committed Aug 19, 2019
1 parent bf9523b commit 8a95e2c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 63 deletions.
88 changes: 39 additions & 49 deletions src/mon/Elector.cc
Expand Up @@ -31,73 +31,68 @@ static ostream& _prefix(std::ostream *_dout, Elector* elector) {
<< ").elector(" << elector->get_epoch() << ") ";
}

void ElectionLogic::persist_epoch(epoch_t e)
void Elector::persist_epoch(epoch_t e)
{
auto t(std::make_shared<MonitorDBStore::Transaction>());
t->put(Monitor::MONITOR_NAME, "election_epoch", e);
elector->mon->store->apply_transaction(t);
mon->store->apply_transaction(t);
}

epoch_t ElectionLogic::read_persisted_epoch()
epoch_t Elector::read_persisted_epoch()
{
return elector->mon->store->get(Monitor::MONITOR_NAME, "election_epoch");
return mon->store->get(Monitor::MONITOR_NAME, "election_epoch");
}

void ElectionLogic::validate_store()
void Elector::validate_store()
{
auto t(std::make_shared<MonitorDBStore::Transaction>());
t->put(Monitor::MONITOR_NAME, "election_writeable_test", rand());
int r = elector->mon->store->apply_transaction(t);
int r = mon->store->apply_transaction(t);
ceph_assert(r >= 0);
}

bool ElectionLogic::elector_is_current_member(int rank)
{
return elector->is_current_member(rank);
}

bool Elector::is_current_member(int rank)
{
return mon->quorum.count(rank);
}

void ElectionLogic::elector_trigger_new_election()
void Elector::trigger_new_election()
{
elector->mon->start_election();
mon->start_election();
}

int ElectionLogic::elector_my_rank()
int Elector::get_my_rank()
{
return elector->mon->rank;
return mon->rank;
}

void ElectionLogic::elector_reset()
void Elector::reset_election()
{
elector->mon->bootstrap();
mon->bootstrap();
}

bool ElectionLogic::elector_ever_participated()
bool Elector::ever_participated()
{
return elector->mon->has_ever_joined;
return mon->has_ever_joined;
}

unsigned ElectionLogic::elector_paxos_size()
unsigned Elector::paxos_size()
{
return (unsigned)elector->mon->monmap->size();
return (unsigned)mon->monmap->size();
}


void ElectionLogic::init()
{
epoch = read_persisted_epoch();
epoch = elector->read_persisted_epoch();
if (!epoch) {
dout(1) << "init, first boot, initializing epoch at 1 " << dendl;
epoch = 1;
} else if (epoch % 2) {
dout(1) << "init, last seen epoch " << epoch
<< ", mid-election, bumping" << dendl;
++epoch;
persist_epoch(epoch);
elector->persist_epoch(epoch);
} else {
dout(1) << "init, last seen epoch " << epoch << dendl;
}
Expand All @@ -113,27 +108,22 @@ void ElectionLogic::bump_epoch(epoch_t e)
dout(10) << __func__ << epoch << " to " << e << dendl;
ceph_assert(epoch <= e);
epoch = e;
validate_store();
elector->validate_store();
// clear up some state
electing_me = false;
acked_me.clear();
elector_bump_epoch();
}

void ElectionLogic::elector_bump_epoch()
{
elector->_bump_epoch();
elector->notify_bump_epoch();
}

void Elector::_bump_epoch()
void Elector::notify_bump_epoch()
{
peer_info.clear();
mon->join_election();
}

void ElectionLogic::declare_standalone_victory()
{
assert(elector_paxos_size() == 1 && elector_my_rank() == 0);
assert(elector->paxos_size() == 1 && elector->get_my_rank() == 0);
init();
bump_epoch(epoch+1);
}
Expand All @@ -153,26 +143,26 @@ void ElectionLogic::start()
if (epoch % 2 == 0) {
bump_epoch(epoch+1); // odd == election cycle
} else {
validate_store();
elector->validate_store();
}
electing_me = true;
acked_me.insert(elector_my_rank());
acked_me.insert(elector->get_my_rank());
leader_acked = -1;

elector_propose_to_peers(epoch);
elector->propose_to_peers(epoch);
elector->_start();
}

void ElectionLogic::elector_propose_to_peers(epoch_t e)
void Elector::propose_to_peers(epoch_t e)
{
// bcast to everyone else
for (unsigned i=0; i<elector->mon->monmap->size(); ++i) {
if ((int)i == elector->mon->rank) continue;
for (unsigned i=0; i<mon->monmap->size(); ++i) {
if ((int)i == mon->rank) continue;
MMonElection *m =
new MMonElection(MMonElection::OP_PROPOSE, e, elector->mon->monmap);
new MMonElection(MMonElection::OP_PROPOSE, e, mon->monmap);
m->mon_features = ceph::features::mon::get_supported();
m->mon_release = ceph_release();
elector->mon->send_mon_message(m, i);
mon->send_mon_message(m, i);
}
}

Expand Down Expand Up @@ -254,15 +244,15 @@ void ElectionLogic::end_election_period()

// did i win?
if (electing_me &&
acked_me.size() > (elector_paxos_size() / 2)) {
acked_me.size() > (elector->paxos_size() / 2)) {
// i win
declare_victory();
} else {
// whoever i deferred to didn't declare victory quickly enough.
if (elector_ever_participated())
if (elector->ever_participated())
start();
else
elector_reset();
elector->reset_election();
}
}

Expand Down Expand Up @@ -374,27 +364,27 @@ void ElectionLogic::receive_propose(epoch_t mepoch, int from)
} else if (mepoch < epoch) {
// got an "old" propose,
if (epoch % 2 == 0 && // in a non-election cycle
!elector_is_current_member(from)) { // from someone outside the quorum
!elector->is_current_member(from)) { // from someone outside the quorum
// a mon just started up, call a new election so they can rejoin!
dout(5) << " got propose from old epoch, "
<< from << " must have just started" << dendl;
// we may be active; make sure we reset things in the monitor appropriately.
elector_trigger_new_election();
elector->trigger_new_election();
} else {
dout(5) << " ignoring old propose" << dendl;
return;
}
}

if (elector_my_rank() < from) {
if (elector->get_my_rank() < from) {
// i would win over them.
if (leader_acked >= 0) { // we already acked someone
ceph_assert(leader_acked < from); // and they still win, of course
dout(5) << "no, we already acked " << leader_acked << dendl;
} else {
// wait, i should win!
if (!electing_me) {
elector_trigger_new_election();
elector->trigger_new_election();
}
}
} else {
Expand Down Expand Up @@ -422,7 +412,7 @@ void ElectionLogic::receive_ack(int from, epoch_t from_epoch)
// is that _everyone_?
if (electing_me) {
acked_me.insert(from);
if (acked_me.size() == elector_paxos_size()) {
if (acked_me.size() == elector->paxos_size()) {
// if yes, shortcut to election finish
declare_victory();
}
Expand Down Expand Up @@ -483,7 +473,7 @@ void Elector::handle_ack(MonOpRequestRef op)

bool ElectionLogic::receive_victory_claim(int from, epoch_t from_epoch)
{
ceph_assert(from < elector_my_rank());
ceph_assert(from < elector->get_my_rank());
ceph_assert(from_epoch % 2 == 0);

leader_acked = -1;
Expand Down
39 changes: 25 additions & 14 deletions src/mon/Elector.h
Expand Up @@ -24,8 +24,21 @@
#include "mon/mon_types.h"

class Monitor;

class Elector;
class ElectionOwner {
public:
virtual void persist_epoch(epoch_t e) = 0;
virtual epoch_t read_persisted_epoch() = 0;
virtual void validate_store() = 0;
virtual void notify_bump_epoch() = 0;
virtual void trigger_new_election() = 0;
virtual int get_my_rank() = 0;
virtual void propose_to_peers(epoch_t e) = 0;
virtual void reset_election() = 0;
virtual bool ever_participated() = 0;
virtual unsigned paxos_size() = 0;
virtual ~ElectionOwner() = 0;
};

class ElectionLogic {
public:
Expand All @@ -51,18 +64,6 @@ class ElectionLogic {
void init();
void bump_epoch(epoch_t e);
void declare_victory();
// call-outs
void persist_epoch(epoch_t e);
epoch_t read_persisted_epoch();
void validate_store();
void elector_bump_epoch();
bool elector_is_current_member(int rank);
void elector_trigger_new_election();
int elector_my_rank();
void elector_propose_to_peers(epoch_t e);
void elector_reset();
bool elector_ever_participated();
unsigned elector_paxos_size();
};

/**
Expand Down Expand Up @@ -105,6 +106,16 @@ class Elector {
// FIXME!
public:
Monitor *mon;
void persist_epoch(epoch_t e);
epoch_t read_persisted_epoch();
void validate_store();
void trigger_new_election();
int get_my_rank();
void propose_to_peers(epoch_t e);
void reset_election();
bool ever_participated();
unsigned paxos_size();

private:

/**
Expand Down Expand Up @@ -200,7 +211,7 @@ class Elector {
*
* @param e Epoch to which we will update our epoch
*/
void _bump_epoch();
void notify_bump_epoch();

/**
* Start new elections by proposing ourselves as the new Leader.
Expand Down

0 comments on commit 8a95e2c

Please sign in to comment.