willemt/raft

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);
}

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).

thanks! This change was landed by 9bdf41b