Better Leader Commit?
UncP opened this issue · 2 comments
UncP commented
in raft_recv_appendentries_response(raft_server_t* me_, raft_node_t* node, msg_appendentries_response_t* r)
int votes = 1;
int point = r->current_idx;
int i;
for (i = 0; i < me->num_nodes; i++)
{
if (me->node == me->nodes[i] || !raft_node_is_voting(me->nodes[i]))
continue;
int match_idx = raft_node_get_match_idx(me->nodes[i]);
if (0 < match_idx)
{
raft_entry_t* ety = raft_get_entry_from_idx(me_, match_idx);
if (ety->term == me->current_term && point <= match_idx)
votes++;
}
}
if (raft_get_num_voting_nodes(me_) / 2 < votes && raft_get_commit_idx(me_) < point)
raft_set_commit_idx(me_, point);
I add an if before the loop in the code based on two reasons:
- we first check if commit index < point to avoid unnecessary loop
- the raft paper said if we are going to change leader's commit index to point, we only need to make sure that log[point].term == current_term
int point = r->current_idx;
raft_entry_t* ety = raft_get_entry_from_idx(me_, point)
if (raft_get_commit_idx(me_) < point && ety->term == me->current_term)
{
int votes = 1;
int i;
for (i = 0; i < me->num_nodes; i++)
{
if (me->node == me->nodes[i] || !raft_node_is_voting(me->nodes[i]))
continue;
int match_idx = raft_node_get_match_idx(me->nodes[i]);
if (match_idx >= point)
vote++;
}
if (raft_get_num_voting_nodes(me_) / 2 < votes)
raft_set_commit_idx(me_, point);
}
willemt commented
thanks for the suggestion!
The change is failing inside my simulator (https://github.com/willemt/virtraft). That means I have to do some more analysis, and add a unit test for this (the current unit tests don't fail when I add this change).