Commit c0616495 authored by Willem Thiart's avatar Willem Thiart
Browse files

Add raft_node_is_voting

parent 1297265f
......@@ -573,4 +573,13 @@ int raft_get_state(raft_server_t* me_);
* @return the last log term */
int raft_get_last_log_term(raft_server_t* me_);
/** Turn a node into a voting node.
* Voting nodes can take part in elections and in-regards to commiting entries,
* are counted in majorities. */
void raft_node_set_voting(raft_node_t* node, int voting);
/* Tell if a node is a voting node or not.
* @return 1 if this is a voting node. Otherwise 0. */
int raft_node_is_voting(raft_node_t* me_);
#endif /* RAFT_H_ */
......@@ -16,6 +16,9 @@
#include "raft.h"
#define RAFT_NODE_VOTED_FOR_ME 1
#define RAFT_NODE_VOTING 1 << 1
typedef struct
{
void* udata;
......@@ -23,8 +26,7 @@ typedef struct
int next_idx;
int match_idx;
/* 1 if node has voted for me */
int voted_for_me;
int flags;
int id;
} raft_node_private_t;
......@@ -37,6 +39,7 @@ raft_node_t* raft_node_new(void* udata, int id)
me->next_idx = 1;
me->match_idx = 0;
me->id = id;
me->flags = RAFT_NODE_VOTING;
return (raft_node_t*)me;
}
......@@ -80,13 +83,32 @@ void raft_node_set_udata(raft_node_t* me_, void* udata)
void raft_node_vote_for_me(raft_node_t* me_, const int vote)
{
raft_node_private_t* me = (raft_node_private_t*)me_;
me->voted_for_me = vote;
if (vote)
me->flags |= RAFT_NODE_VOTED_FOR_ME;
else
me->flags &= ~RAFT_NODE_VOTED_FOR_ME;
}
int raft_node_has_vote_for_me(raft_node_t* me_)
{
raft_node_private_t* me = (raft_node_private_t*)me_;
return me->voted_for_me;
return (me->flags & RAFT_NODE_VOTED_FOR_ME) != 0;
}
void raft_node_set_voting(raft_node_t* me_, int voting)
{
raft_node_private_t* me = (raft_node_private_t*)me_;
if (voting)
me->flags |= RAFT_NODE_VOTING;
else
me->flags &= ~RAFT_NODE_VOTING;
}
int raft_node_is_voting(raft_node_t* me_)
{
raft_node_private_t* me = (raft_node_private_t*)me_;
return (me->flags & RAFT_NODE_VOTING) != 0;
}
int raft_node_get_id(raft_node_t* me_)
......
......@@ -92,13 +92,13 @@ void raft_become_leader(raft_server_t* me_)
raft_set_state(me_, RAFT_STATE_LEADER);
for (i = 0; i < me->num_nodes; i++)
{
if (me->node != me->nodes[i])
{
raft_node_t* node = me->nodes[i];
raft_node_set_next_idx(node, raft_get_current_idx(me_) + 1);
raft_node_set_match_idx(node, 0);
raft_send_appendentries(me_, node);
}
if (me->node == me->nodes[i] || !raft_node_is_voting(me->nodes[i]))
continue;
raft_node_t* node = me->nodes[i];
raft_node_set_next_idx(node, raft_get_current_idx(me_) + 1);
raft_node_set_match_idx(node, 0);
raft_send_appendentries(me_, node);
}
}
......@@ -121,7 +121,7 @@ void raft_become_candidate(raft_server_t* me_)
me->timeout_elapsed = rand() % me->election_timeout;
for (i = 0; i < me->num_nodes; i++)
if (me->node != me->nodes[i])
if (me->node != me->nodes[i] && raft_node_is_voting(me->nodes[i]))
raft_send_requestvote(me_, me->nodes[i]);
}
......@@ -226,7 +226,7 @@ int raft_recv_appendentries_response(raft_server_t* me_,
int i;
for (i = 0; i < me->num_nodes; i++)
{
if (me->node == me->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]);
......@@ -521,15 +521,17 @@ int raft_recv_entry(raft_server_t* me_, raft_node_t* node, msg_entry_t* e,
memcpy(&ety.data, &e->data, sizeof(raft_entry_data_t));
raft_append_entry(me_, &ety);
for (i = 0; i < me->num_nodes; i++)
{
if (me->node == me->nodes[i] || !raft_node_is_voting(me->nodes[i]))
continue;
/* Only send new entries.
* Don't send the entry to peers who are behind, to prevent them from
* becomming congested. */
if (me->node != me->nodes[i])
{
int next_idx = raft_node_get_next_idx(me->nodes[i]);
if (next_idx == raft_get_current_idx(me_))
raft_send_appendentries(me_, me->nodes[i]);
}
* becoming congested. */
int next_idx = raft_node_get_next_idx(me->nodes[i]);
if (next_idx == raft_get_current_idx(me_))
raft_send_appendentries(me_, me->nodes[i]);
}
/* if we're the only node, we can consider the entry committed */
if (1 == me->num_nodes)
......@@ -649,7 +651,7 @@ void raft_send_appendentries_all(raft_server_t* me_)
me->timeout_elapsed = 0;
for (i = 0; i < me->num_nodes; i++)
if (me->node != me->nodes[i])
if (me->node != me->nodes[i] && raft_node_is_voting(me->nodes[i]))
raft_send_appendentries(me_, me->nodes[i]);
}
......@@ -678,7 +680,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
int i, votes;
for (i = 0, votes = 0; i < me->num_nodes; i++)
if (me->node != me->nodes[i])
if (me->node != me->nodes[i] && raft_node_is_voting(me->nodes[i]))
if (raft_node_has_vote_for_me(me->nodes[i]))
votes += 1;
......
......@@ -10,11 +10,15 @@
#include "raft_log.h"
#include "raft_private.h"
void TestRaft_node_set_nextIdx(CuTest * tc)
void TestRaft_is_voting_by_default(CuTest * tc)
{
raft_node_t *p;
raft_node_t *p = raft_node_new((void*)1, 1);
CuAssertTrue(tc, raft_node_is_voting(p));
}
p = raft_node_new((void*)1, 1);
void TestRaft_node_set_nextIdx(CuTest * tc)
{
raft_node_t *p = raft_node_new((void*)1, 1);
raft_node_set_next_idx(p, 3);
CuAssertTrue(tc, 3 == raft_node_get_next_idx(p));
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment