Commit 8f57dc94 authored by Willem Thiart's avatar Willem Thiart
Browse files

Add restrictions to adding nodes

parent edf417f6
......@@ -339,6 +339,8 @@ void raft_set_callbacks(raft_server_t* me, raft_cbs_t* funcs, void* user_data);
* @note This library does not yet support membership changes.
* Once raft_periodic has been run this will fail.
*
* If a voting node already exists the call will fail.
*
* @note The order this call is made is important.
* This call MUST be made in the same order as the other raft nodes.
* This is because the node ID is assigned depending on when this call is made
......@@ -351,13 +353,19 @@ void raft_set_callbacks(raft_server_t* me, raft_cbs_t* funcs, void* user_data);
* @param[in] id The integer ID of this node
* This is used for identifying clients across sessions.
* @param[in] is_self Set to 1 if this "node" is this server
* @return node on success; otherwise NULL */
* @return
* node if it was successfully added;
* NULL if the node already exists */
raft_node_t* raft_add_node(raft_server_t* me, void* user_data, int id, int is_self);
#define raft_add_peer raft_add_node
/** Add a node which does not participate in voting.
* Parameters are identical to raft_add_node */
* If a node already exists the call will fail.
* Parameters are identical to raft_add_node
* @return
* node if it was successfully added;
* NULL if the node already exists */
raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, int id, int is_self);
/** Remove node.
......
......@@ -754,10 +754,16 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, int id, int is_self)
/* set to voting if node already exists */
raft_node_t* node = raft_get_node(me_, id);
if (node)
{
if (!raft_node_is_voting(node))
{
raft_node_set_voting(node, 1);
return node;
}
else
/* we shouldn't add a node twice */
return NULL;
}
me->num_nodes++;
me->nodes = (raft_node_t*)realloc(me->nodes, sizeof(raft_node_t*) * me->num_nodes);
......@@ -771,7 +777,13 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, int id, int is_self)
raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, int id, int is_self)
{
if (raft_get_node(me_, id))
return NULL;
raft_node_t* node = raft_add_node(me_, udata, id, is_self);
if (!node)
return NULL;
raft_node_set_voting(node, 0);
return node;
}
......
......@@ -80,6 +80,36 @@ void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc)
CuAssertIntEquals(tc, 1, raft_get_num_nodes(r));
}
void TestRaft_server_add_node_with_already_existing_id_is_not_allowed(CuTest * tc)
{
void *r = raft_new();
raft_add_node(r, NULL, 9, 0);
raft_add_node(r, NULL, 11, 0);
CuAssertTrue(tc, NULL == raft_add_node(r, NULL, 9, 0));
CuAssertTrue(tc, NULL == raft_add_node(r, NULL, 11, 0));
}
void TestRaft_server_add_non_voting_node_with_already_existing_id_is_not_allowed(CuTest * tc)
{
void *r = raft_new();
raft_add_non_voting_node(r, NULL, 9, 0);
raft_add_non_voting_node(r, NULL, 11, 0);
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 9, 0));
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 11, 0));
}
void TestRaft_server_add_non_voting_node_with_already_existing_voting_id_is_not_allowed(CuTest * tc)
{
void *r = raft_new();
raft_add_node(r, NULL, 9, 0);
raft_add_node(r, NULL, 11, 0);
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 9, 0));
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 11, 0));
}
void TestRaft_server_remove_node(CuTest * tc)
{
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