Unverified Commit 736f28b9 authored by Willem's avatar Willem Committed by GitHub
Browse files

Merge pull request #80 from yossigo/pass-entry-to-membership

Add raft_entry_t to membership event callback.
parents b1722ead 072c6003
...@@ -445,19 +445,17 @@ It's highly recommended that when a node is added to the cluster that its node I ...@@ -445,19 +445,17 @@ It's highly recommended that when a node is added to the cluster that its node I
1. Append the configuration change using ``raft_recv_entry``. Make sure the entry has the type set to ``RAFT_LOGTYPE_ADD_NONVOTING_NODE`` 1. Append the configuration change using ``raft_recv_entry``. Make sure the entry has the type set to ``RAFT_LOGTYPE_ADD_NONVOTING_NODE``
2. Inside the ``log_offer`` callback, when a log with type ``RAFT_LOGTYPE_ADD_NONVOTING_NODE`` is detected, we add a non-voting node by calling ``raft_add_non_voting_node``. 2. Once ``node_has_sufficient_logs`` callback fires, append a configuration finalization log entry using ``raft_recv_entry``. Make sure the entry has a type set to ``RAFT_LOGTYPE_ADD_NODE``
3. Once ``node_has_sufficient_logs`` callback fires, append a configuration finalization log entry using ``raft_recv_entry``. Make sure the entry has a type set to ``RAFT_LOGTYPE_ADD_NODE``
4. Inside the ``log_offer`` callback, when you receive a log with type ``RAFT_LOGTYPE_ADD_NODE``, we then set the node to voting by using ``raft_add_node``
**Removing a node** **Removing a node**
1. Append the configuration change using ``raft_recv_entry``. Make sure the entry has the type set to ``RAFT_LOGTYPE_REMOVE_NODE`` 1. Append the configuration change using ``raft_recv_entry``. Make sure the entry has the type set to ``RAFT_LOGTYPE_REMOVE_NODE``
2. Inside the ``log_offer`` callback, when a log with type ``RAFT_LOGTYPE_REMOVE_NODE`` is detected, we remove the node by calling ``raft_remove_node`` 2. Once the ``RAFT_LOGTYPE_REMOVE_NODE`` configuration change log is applied in the ``applylog`` callback we shutdown the server if it is to be removed.
**Membership callback**
3. Once the ``RAFT_LOGTYPE_REMOVE_NODE`` configuration change log is applied in the ``applylog`` callback we shutdown the server if it is to be removed. The ``notify_membership_event`` callback can be used to track nodes as they are added and removed as a result of configuration change log entries. A typical use case is to create and destroy connections to nodes, using connection information obtained from the configuration change log entry.
Log Compaction Log Compaction
-------------- --------------
......
...@@ -349,6 +349,7 @@ typedef int ( ...@@ -349,6 +349,7 @@ typedef int (
* @param[in] raft The Raft server making this callback * @param[in] raft The Raft server making this callback
* @param[in] user_data User data that is passed from Raft server * @param[in] user_data User data that is passed from Raft server
* @param[in] node The node that is the subject of this log. Could be NULL. * @param[in] node The node that is the subject of this log. Could be NULL.
* @param[in] entry The entry that was the trigger for the event. Could be NULL.
* @param[in] type The type of membership change */ * @param[in] type The type of membership change */
typedef void ( typedef void (
*func_membership_event_f *func_membership_event_f
...@@ -356,6 +357,7 @@ typedef void ( ...@@ -356,6 +357,7 @@ typedef void (
raft_server_t* raft, raft_server_t* raft,
void *user_data, void *user_data,
raft_node_t *node, raft_node_t *node,
raft_entry_t *entry,
raft_membership_e type raft_membership_e type
); );
......
...@@ -953,7 +953,7 @@ int raft_send_appendentries_all(raft_server_t* me_) ...@@ -953,7 +953,7 @@ int raft_send_appendentries_all(raft_server_t* me_)
return 0; return 0;
} }
raft_node_t* raft_add_node(raft_server_t* me_, void* udata, raft_node_id_t id, int is_self) raft_node_t* raft_add_node_internal(raft_server_t* me_, raft_entry_t *ety, void* udata, raft_node_id_t id, int is_self)
{ {
raft_server_private_t* me = (raft_server_private_t*)me_; raft_server_private_t* me = (raft_server_private_t*)me_;
...@@ -988,17 +988,22 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, raft_node_id_t id, i ...@@ -988,17 +988,22 @@ raft_node_t* raft_add_node(raft_server_t* me_, void* udata, raft_node_id_t id, i
node = me->nodes[me->num_nodes - 1]; node = me->nodes[me->num_nodes - 1];
if (me->cb.notify_membership_event) if (me->cb.notify_membership_event)
me->cb.notify_membership_event(me_, raft_get_udata(me_), node, RAFT_MEMBERSHIP_ADD); me->cb.notify_membership_event(me_, raft_get_udata(me_), node, ety, RAFT_MEMBERSHIP_ADD);
return node; return node;
} }
raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, raft_node_id_t id, int is_self) raft_node_t* raft_add_node(raft_server_t* me_, void* udata, raft_node_id_t id, int is_self)
{
return raft_add_node_internal(me_, NULL, udata, id, is_self);
}
static raft_node_t* raft_add_non_voting_node_internal(raft_server_t* me_, raft_entry_t *ety, void* udata, raft_node_id_t id, int is_self)
{ {
if (raft_get_node(me_, id)) if (raft_get_node(me_, id))
return NULL; return NULL;
raft_node_t* node = raft_add_node(me_, udata, id, is_self); raft_node_t* node = raft_add_node_internal(me_, ety, udata, id, is_self);
if (!node) if (!node)
return NULL; return NULL;
...@@ -1006,12 +1011,17 @@ raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, raft_node ...@@ -1006,12 +1011,17 @@ raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, raft_node
return node; return node;
} }
raft_node_t* raft_add_non_voting_node(raft_server_t* me_, void* udata, raft_node_id_t id, int is_self)
{
return raft_add_non_voting_node_internal(me_, NULL, udata, id, is_self);
}
void raft_remove_node(raft_server_t* me_, raft_node_t* node) void raft_remove_node(raft_server_t* me_, raft_node_t* node)
{ {
raft_server_private_t* me = (raft_server_private_t*)me_; raft_server_private_t* me = (raft_server_private_t*)me_;
if (me->cb.notify_membership_event) if (me->cb.notify_membership_event)
me->cb.notify_membership_event(me_, raft_get_udata(me_), node, RAFT_MEMBERSHIP_REMOVE); me->cb.notify_membership_event(me_, raft_get_udata(me_), node, NULL, RAFT_MEMBERSHIP_REMOVE);
assert(node); assert(node);
...@@ -1136,14 +1146,14 @@ void raft_offer_log(raft_server_t* me_, raft_entry_t* ety, const raft_index_t id ...@@ -1136,14 +1146,14 @@ void raft_offer_log(raft_server_t* me_, raft_entry_t* ety, const raft_index_t id
} }
else if (!node) else if (!node)
{ {
node = raft_add_non_voting_node(me_, NULL, node_id, is_self); node = raft_add_non_voting_node_internal(me_, ety, NULL, node_id, is_self);
assert(node); assert(node);
} }
} }
break; break;
case RAFT_LOGTYPE_ADD_NODE: case RAFT_LOGTYPE_ADD_NODE:
node = raft_add_node(me_, NULL, node_id, is_self); node = raft_add_node_internal(me_, ety, NULL, node_id, is_self);
assert(node); assert(node);
assert(raft_node_is_voting(node)); assert(raft_node_is_voting(node));
break; break;
......
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