void TestRaft_follower_recv_appendentries_does_not_log_if_no_entries_are_specified( CuTest * tc) { msg_appendentries_t ae; msg_appendentries_response_t aer; void *r = raft_new(); raft_add_node(r, (void*)1, 1); raft_add_node(r, (void*)2, 0); raft_set_state(r, RAFT_STATE_FOLLOWER); /* log size s */ CuAssertTrue(tc, 0 == raft_get_log_count(r)); /* receive an appendentry with commit */ memset(&ae, 0, sizeof(msg_appendentries_t)); ae.term = 1; ae.prev_log_term = 1; ae.prev_log_idx = 4; ae.leader_commit = 5; ae.n_entries = 0; raft_recv_appendentries(r, 1, &ae, &aer); CuAssertTrue(tc, 0 == raft_get_log_count(r)); }
/* If commitidx > lastApplied: increment lastApplied, apply log[lastApplied] * to state machine (§5.3) */ void TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx( CuTest* tc) { raft_entry_t ety; void *r = raft_new(); /* must be follower */ raft_set_state(r, RAFT_STATE_FOLLOWER); raft_set_current_term(r, 1); raft_set_commit_idx(r, 1); raft_set_last_applied_idx(r, 0); /* need at least one entry */ ety.term = 1; ety.id = 1; ety.data.buf = "aaa"; ety.data.len = 3; raft_append_entry(r, &ety); /* let time lapse */ raft_periodic(r, 1); CuAssertTrue(tc, 0 != raft_get_last_applied_idx(r)); CuAssertTrue(tc, 1 == raft_get_last_applied_idx(r)); }
void raft_become_follower(raft_server_t* me_) { raft_server_private_t* me = (void*)me_; __log(me_, NULL, "becoming follower"); raft_set_state(me_, RAFT_STATE_FOLLOWER); me->voted_for = -1; }
raft_server_t* raft_new() { raft_server_private_t* me = (raft_server_private_t*)calloc(1, sizeof(raft_server_private_t)); if (!me) return NULL; me->current_term = 0; me->voted_for = -1; me->current_idx = 1; me->timeout_elapsed = 0; me->request_timeout = 200; me->election_timeout = 1000; me->log = log_new(); raft_set_state((raft_server_t*)me, RAFT_STATE_FOLLOWER); return (raft_server_t*)me; }
void raft_become_leader(raft_server_t* me_) { raft_server_private_t* me = (void*)me_; int i; __log(me_, NULL, "becoming leader"); raft_set_state(me_,RAFT_STATE_LEADER); me->voted_for = -1; for (i=0; i<me->num_nodes; i++) { if (me->nodeid == i) continue; raft_node_t* p = raft_get_node(me_, i); raft_node_set_next_idx(p, raft_get_current_idx(me_)+1); raft_send_appendentries(me_, i); } }
void raft_clear(raft_server_t* me_) { raft_server_private_t* me = (raft_server_private_t*)me_; me->current_term = 0; me->voted_for = -1; me->timeout_elapsed = 0; me->voting_cfg_change_log_idx = -1; raft_set_state((raft_server_t*)me, RAFT_STATE_FOLLOWER); me->current_leader = NULL; me->commit_idx = 0; me->last_applied_idx = 0; me->num_nodes = 0; me->node = NULL; me->voting_cfg_change_log_idx = 0; log_clear(me->log); }
void raft_become_leader(raft_server_t* me_) { raft_server_private_t* me = (raft_server_private_t*)me_; int i; __log(me_, NULL, "becoming leader term:%d", raft_get_current_term(me_)); raft_set_state(me_, RAFT_STATE_LEADER); for (i = 0; i < me->num_nodes; i++) { 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); } }
void raft_become_candidate(raft_server_t* me_) { raft_server_private_t* me = (raft_server_private_t*)me_; int i; __log(me_, "becoming candidate"); memset(me->votes_for_me, 0, sizeof(int) * me->num_nodes); me->current_term += 1; raft_vote(me_, me->nodeid); raft_set_state(me_, RAFT_STATE_CANDIDATE); /* we need a random factor here to prevent simultaneous candidates */ me->timeout_elapsed = rand() % 500; for (i = 0; i < me->num_nodes; i++) if (me->nodeid != i) raft_send_requestvote(me_, i); }
void raft_become_candidate(raft_server_t* me_) { raft_server_private_t* me = (raft_server_private_t*)me_; int i; __log(me_, NULL, "becoming candidate"); raft_set_current_term(me_, raft_get_current_term(me_) + 1); for (i = 0; i < me->num_nodes; i++) raft_node_vote_for_me(me->nodes[i], 0); raft_vote(me_, me->node); me->current_leader = NULL; raft_set_state(me_, RAFT_STATE_CANDIDATE); /* we need a random factor here to prevent simultaneous candidates */ /* TODO: this should probably be lower */ me->timeout_elapsed = rand() % me->election_timeout; for (i = 0; i < me->num_nodes; i++) if (me->node != me->nodes[i] && raft_node_is_voting(me->nodes[i])) raft_send_requestvote(me_, me->nodes[i]); }
void TestRaft_follower_recv_appendentries_increases_log(CuTest * tc) { msg_appendentries_t ae; msg_entry_t ety; msg_appendentries_response_t aer; char *str = "aaa"; void *r = raft_new(); raft_add_node(r, (void*)1, 1); raft_add_node(r, (void*)2, 0); raft_set_state(r, RAFT_STATE_FOLLOWER); /* log size s */ CuAssertTrue(tc, 0 == raft_get_log_count(r)); /* receive an appendentry with commit */ memset(&ae, 0, sizeof(msg_appendentries_t)); ae.term = 3; ae.prev_log_term = 1; /* first appendentries msg */ ae.prev_log_idx = 0; ae.leader_commit = 5; /* include one entry */ memset(&ety, 0, sizeof(msg_entry_t)); ety.data.buf = str; ety.data.len = 3; ety.id = 1; /* check that old terms are passed onto the log */ ety.term = 2; ae.entries = &ety; ae.n_entries = 1; raft_recv_appendentries(r, 1, &ae, &aer); CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == raft_get_log_count(r)); raft_entry_t* log = raft_get_entry_from_idx(r, 1); CuAssertTrue(tc, 2 == log->term); }
void raft_become_follower(raft_server_t* me_) { __log(me_, NULL, "becoming follower"); raft_set_state(me_, RAFT_STATE_FOLLOWER); }
void TestRaft_set_state(CuTest * tc) { void *r = raft_new(); raft_set_state(r, RAFT_STATE_LEADER); CuAssertTrue(tc, RAFT_STATE_LEADER == raft_get_state(r)); }