Commit 2b469cbf authored by Willem Thiart's avatar Willem Thiart
Browse files

Allow single voting node to become leader

It makes sense that a single voting node should be able to receive
entries. This prevents deadlocks in cases where the cluster removes
all but one node.
parent 36daccba
...@@ -160,6 +160,12 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period) ...@@ -160,6 +160,12 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period)
me->timeout_elapsed += msec_since_last_period; me->timeout_elapsed += msec_since_last_period;
/* Only one voting node means it's safe for us to become the leader */
if (1 == raft_get_num_voting_nodes(me_) &&
raft_node_is_voting(raft_get_my_node((void*)me)) &&
!raft_is_leader(me_))
raft_become_leader(me_);
if (me->state == RAFT_STATE_LEADER) if (me->state == RAFT_STATE_LEADER)
{ {
if (me->request_timeout <= me->timeout_elapsed) if (me->request_timeout <= me->timeout_elapsed)
......
...@@ -376,10 +376,11 @@ void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc) ...@@ -376,10 +376,11 @@ void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc)
CuAssertTrue(tc, 100 == raft_get_timeout_elapsed(r)); CuAssertTrue(tc, 100 == raft_get_timeout_elapsed(r));
} }
void TestRaft_server_election_timeout_does_no_promote_us_to_leader_if_there_is_only_1_node(CuTest * tc) void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_there_is_are_more_than_1_nodes(CuTest * tc)
{ {
void *r = raft_new(); void *r = raft_new();
raft_add_node(r, NULL, 1, 1); raft_add_node(r, NULL, 1, 1);
raft_add_node(r, NULL, 2, 0);
raft_set_election_timeout(r, 1000); raft_set_election_timeout(r, 1000);
/* clock over (ie. 1000 + 1), causing new election */ /* clock over (ie. 1000 + 1), causing new election */
...@@ -388,6 +389,31 @@ void TestRaft_server_election_timeout_does_no_promote_us_to_leader_if_there_is_o ...@@ -388,6 +389,31 @@ void TestRaft_server_election_timeout_does_no_promote_us_to_leader_if_there_is_o
CuAssertTrue(tc, 0 == raft_is_leader(r)); CuAssertTrue(tc, 0 == raft_is_leader(r));
} }
void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only_1_node(CuTest * tc)
{
void *r = raft_new();
raft_add_node(r, NULL, 1, 1);
raft_set_election_timeout(r, 1000);
/* clock over (ie. 1000 + 1), causing new election */
raft_periodic(r, 1001);
CuAssertTrue(tc, 1 == raft_is_leader(r));
}
void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only_1_voting_node(CuTest * tc)
{
void *r = raft_new();
raft_add_node(r, NULL, 1, 1);
raft_add_non_voting_node(r, NULL, 2, 0);
raft_set_election_timeout(r, 1000);
/* clock over (ie. 1000 + 1), causing new election */
raft_periodic(r, 1001);
CuAssertTrue(tc, 1 == raft_is_leader(r));
}
void TestRaft_server_recv_entry_auto_commits_if_we_are_the_only_node(CuTest * tc) void TestRaft_server_recv_entry_auto_commits_if_we_are_the_only_node(CuTest * tc)
{ {
void *r = raft_new(); void *r = raft_new();
......
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