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); ...@@ -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. * @note This library does not yet support membership changes.
* Once raft_periodic has been run this will fail. * 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. * @note The order this call is made is important.
* This call MUST be made in the same order as the other raft nodes. * 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 * 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); ...@@ -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 * @param[in] id The integer ID of this node
* This is used for identifying clients across sessions. * This is used for identifying clients across sessions.
* @param[in] is_self Set to 1 if this "node" is this server * @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); 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 #define raft_add_peer raft_add_node
/** Add a node which does not participate in voting. /** 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); raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, int id, int is_self);
/** Remove node. /** Remove node.
......
...@@ -755,8 +755,14 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, int id, int is_self) ...@@ -755,8 +755,14 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, int id, int is_self)
raft_node_t* node = raft_get_node(me_, id); raft_node_t* node = raft_get_node(me_, id);
if (node) if (node)
{ {
raft_node_set_voting(node, 1); if (!raft_node_is_voting(node))
return node; {
raft_node_set_voting(node, 1);
return node;
}
else
/* we shouldn't add a node twice */
return NULL;
} }
me->num_nodes++; me->num_nodes++;
...@@ -771,7 +777,13 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, int id, int is_self) ...@@ -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) 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); raft_node_t* node = raft_add_node(me_, udata, id, is_self);
if (!node)
return NULL;
raft_node_set_voting(node, 0); raft_node_set_voting(node, 0);
return node; return node;
} }
......
...@@ -80,6 +80,36 @@ void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc) ...@@ -80,6 +80,36 @@ void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc)
CuAssertIntEquals(tc, 1, raft_get_num_nodes(r)); 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 TestRaft_server_remove_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