raft: expose current_leader in raft::server

The handler for join_node_request will need to know which node is
considered the group 0 leader right now by the local node.

If the topology coordinator crashes and a new node immediately wants to
replace it with the same IP, the node that handles join_node_request
will attempt to perform a read barrier. If this happens quickly enough,
due to the IP reuse the RPC will be sent to the new node instead of the
(now crashed) topology coordinator; the RPC will get an error and will
fail the barrier.

If we detect that the new node wants to replace the current topology
coordinator, the upcoming join_node_request_handler will wait until
there is a leader change.
This commit is contained in:
Piotr Dulikowski
2023-09-22 15:55:44 +02:00
parent 74b01730b4
commit 64668e325e
2 changed files with 10 additions and 0 deletions

View File

@@ -91,6 +91,7 @@ public:
std::pair<index_t, term_t> log_last_idx_term() override;
void elapse_election() override;
bool is_leader() override;
raft::server_id current_leader() const override;
void tick() override;
raft::server_id id() const override;
void set_applier_queue_max_size(size_t queue_max_size) override;
@@ -1645,6 +1646,10 @@ bool server_impl::is_leader() {
return _fsm->is_leader();
}
raft::server_id server_impl::current_leader() const {
return _fsm->current_leader();
}
void server_impl::elapse_election() {
while (_fsm->election_elapsed() < ELECTION_TIMEOUT) {
_fsm->tick();

View File

@@ -228,6 +228,11 @@ public:
// The information is only relevant for the current_term() only
virtual bool is_leader() = 0;
// Returns ID of the server that is thought to be the current leader.
// Returns an empty ID if there is an ongoing election.
// The information is only relevant for the current_term() only.
virtual raft::server_id current_leader() const = 0;
// The function should be called periodically to advance logical clock.
virtual void tick() = 0;