Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Willemt Raft
Commits
33367594
Commit
33367594
authored
Jan 13, 2014
by
willem
Browse files
Better documentation
parent
e95a1a87
Changes
4
Hide whitespace changes
Inline
Side-by-side
raft.h
View file @
33367594
...
@@ -8,26 +8,24 @@
...
@@ -8,26 +8,24 @@
* @version 0.1
* @version 0.1
*/
*/
enum
{
RAFT_STATE_NONE
,
RAFT_STATE_FOLLOWER
,
RAFT_STATE_CANDIDATE
,
RAFT_STATE_LEADER
};
typedef
struct
{
typedef
struct
{
/* So that we can tell which nodes were removed/added */
/** The ID that this node used to have.
* So that we can tell which nodes were removed/added when the
* configuration changes */
int
old_id
;
int
old_id
;
/* User data pointer for addressing.
* ie. This is most likely a (IP,Port) tuple */
/** User data pointer for addressing.
* Examples of what this could be:
* - void* pointing to implementor's networking data
* - a (IP,Port) tuple */
void
*
udata_address
;
void
*
udata_address
;
}
raft_node_configuration_t
;
}
raft_node_configuration_t
;
typedef
struct
{
typedef
struct
{
/*
term
candidate's term */
/* candidate's term */
int
term
;
int
term
;
/*
candidateId
candidate requesting vote */
/* candidate requesting vote */
int
candidate_id
;
int
candidate_id
;
/* idx of candidate's last log entry */
/* idx of candidate's last log entry */
...
@@ -37,25 +35,22 @@ typedef struct {
...
@@ -37,25 +35,22 @@ typedef struct {
int
last_log_term
;
int
last_log_term
;
}
msg_requestvote_t
;
}
msg_requestvote_t
;
/**
* every server must send entrys in this format */
typedef
struct
{
typedef
struct
{
/* the entry's unique ID */
unsigned
int
id
;
unsigned
int
id
;
/* entry data */
unsigned
char
*
data
;
unsigned
char
*
data
;
/* length of entry data */
unsigned
int
len
;
unsigned
int
len
;
}
msg_entry_t
;
}
msg_entry_t
;
typedef
struct
{
typedef
struct
{
unsigned
int
term
;
/* the entry's unique ID */
unsigned
int
id
;
unsigned
int
id
;
unsigned
char
*
data
;
unsigned
int
len
;
/* number of nodes that have this entry */
unsigned
int
nnodes
;
}
raft_entry_t
;
typedef
struct
{
/* whether or not the entry was committed */
unsigned
int
id
;
int
was_committed
;
int
was_committed
;
}
msg_entry_response_t
;
}
msg_entry_response_t
;
...
@@ -85,12 +80,12 @@ typedef struct {
...
@@ -85,12 +80,12 @@ typedef struct {
* prevLogidx and prevLogTerm */
* prevLogidx and prevLogTerm */
int
success
;
int
success
;
/* Non
Raft fields */
/* Non
-
Raft fields
follow:
*/
/* Having the following fields allows us to do less book keeping in
/* Having the following fields allows us to do less book keeping in
* regards to full fledged RPC */
* regards to full fledged RPC */
/* This is the highest log IDX we've received and appended to our log */
/* This is the highest log IDX we've received and appended to our log */
int
current_idx
;
int
current_idx
;
/* The first idx that we received within the append
entries message */
/* The first idx that we received within the appendentries message */
int
first_idx
;
int
first_idx
;
}
msg_appendentries_response_t
;
}
msg_appendentries_response_t
;
...
@@ -106,10 +101,10 @@ enum {
...
@@ -106,10 +101,10 @@ enum {
typedef
int
(
typedef
int
(
*
func_send_f
*
func_send_f
)
(
)
(
void
*
c
aller
,
void
*
c
b_ctx
,
void
*
udata
,
void
*
udata
,
int
node
,
int
node
,
int
type
,
int
msg_
type
,
const
unsigned
char
*
send_data
,
const
unsigned
char
*
send_data
,
const
int
len
const
int
len
);
);
...
@@ -119,17 +114,19 @@ typedef int (
...
@@ -119,17 +114,19 @@ typedef int (
typedef
void
(
typedef
void
(
*
func_log_f
*
func_log_f
)
(
)
(
void
*
udata
,
void
*
cb_ctx
,
void
*
src
,
void
*
src
,
const
char
*
buf
,
const
char
*
buf
,
...
...
);
);
#endif
#endif
/**
* Apply this log to the state macine */
typedef
int
(
typedef
int
(
*
func_applylog_f
*
func_applylog_f
)
(
)
(
void
*
c
aller
,
void
*
c
b_ctx
,
void
*
udata
,
void
*
udata
,
const
unsigned
char
*
data
,
const
unsigned
char
*
data
,
const
int
len
const
int
len
...
@@ -144,6 +141,19 @@ typedef struct {
...
@@ -144,6 +141,19 @@ typedef struct {
typedef
void
*
raft_server_t
;
typedef
void
*
raft_server_t
;
typedef
void
*
raft_node_t
;
typedef
void
*
raft_node_t
;
typedef
struct
{
/* entry's term */
unsigned
int
term
;
/* the entry's unique ID */
unsigned
int
id
;
/* entry data */
unsigned
char
*
data
;
/* length of entry data */
unsigned
int
len
;
/* number of nodes that have this entry */
unsigned
int
nnodes
;
}
raft_entry_t
;
/**
/**
* Initialise a new raft server
* Initialise a new raft server
* Election timeout defaults to 1000 milliseconds */
* Election timeout defaults to 1000 milliseconds */
...
@@ -162,16 +172,18 @@ void raft_set_callbacks(raft_server_t* me, raft_cbs_t* funcs, void* cb_ctx);
...
@@ -162,16 +172,18 @@ void raft_set_callbacks(raft_server_t* me, raft_cbs_t* funcs, void* cb_ctx);
/**
/**
* Set configuration
* Set configuration
* @param nodes Array of nodes, end of array is marked by NULL entry
* @param nodes Array of nodes, end of array is marked by NULL entry
* @param m
e
_idx Which node is myself */
* @param m
y
_idx Which node is myself */
void
raft_set_configuration
(
raft_server_t
*
me_
,
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_node_configuration_t
*
nodes
,
int
m
e
_idx
);
raft_node_configuration_t
*
nodes
,
int
m
y
_idx
);
/**
/**
* Set election timeout */
* Set election timeout
* @param millisec Election timeout in milliseconds */
void
raft_set_election_timeout
(
raft_server_t
*
me
,
int
millisec
);
void
raft_set_election_timeout
(
raft_server_t
*
me
,
int
millisec
);
/**
/**
* Set request timeout */
* Set request timeout in milliseconds
* @param millisec Request timeout in milliseconds */
void
raft_set_request_timeout
(
raft_server_t
*
me_
,
int
millisec
);
void
raft_set_request_timeout
(
raft_server_t
*
me_
,
int
millisec
);
/**
/**
...
@@ -211,11 +223,19 @@ int raft_recv_requestvote_response(raft_server_t* me, int node,
...
@@ -211,11 +223,19 @@ int raft_recv_requestvote_response(raft_server_t* me, int node,
msg_requestvote_response_t
*
r
);
msg_requestvote_response_t
*
r
);
/**
/**
* Receive an ENTRY message.
* Receive an entry message from client.
* Append entry to log
* Append the entry to the log
* Send APPENDENTRIES to followers */
* Send appendentries to followers
int
raft_recv_entry
(
raft_server_t
*
me
,
int
node
,
msg_entry_t
*
cmd
);
* @param node The node this response was sent by
* @param e The entry message */
int
raft_recv_entry
(
raft_server_t
*
me
,
int
node
,
msg_entry_t
*
e
);
/**
* @return the server's node ID */
int
raft_get_nodeid
(
raft_server_t
*
me_
);
/**
* @return currently configured election timeout in milliseconds */
int
raft_get_election_timeout
(
raft_server_t
*
me
);
int
raft_get_election_timeout
(
raft_server_t
*
me
);
/**
/**
...
@@ -226,29 +246,52 @@ int raft_get_num_nodes(raft_server_t* me);
...
@@ -226,29 +246,52 @@ int raft_get_num_nodes(raft_server_t* me);
* @return number of items within log */
* @return number of items within log */
int
raft_get_log_count
(
raft_server_t
*
me
);
int
raft_get_log_count
(
raft_server_t
*
me
);
/**
* @return current term */
int
raft_get_current_term
(
raft_server_t
*
me
);
int
raft_get_current_term
(
raft_server_t
*
me
);
/**
* @return current log index */
int
raft_get_current_idx
(
raft_server_t
*
me
);
int
raft_get_current_idx
(
raft_server_t
*
me
);
/**
* @return 1 if follower; 0 otherwise */
int
raft_is_follower
(
raft_server_t
*
me
);
int
raft_is_follower
(
raft_server_t
*
me
);
/**
* @return 1 if leader; 0 otherwise */
int
raft_is_leader
(
raft_server_t
*
me
);
int
raft_is_leader
(
raft_server_t
*
me
);
/**
* @return 1 if candidate; 0 otherwise */
int
raft_is_candidate
(
raft_server_t
*
me
);
int
raft_is_candidate
(
raft_server_t
*
me
);
/**
* @return currently elapsed timeout in milliseconds */
int
raft_get_timeout_elapsed
(
raft_server_t
*
me
);
int
raft_get_timeout_elapsed
(
raft_server_t
*
me
);
/**
* @return index of last applied entry */
int
raft_get_last_applied_idx
(
raft_server_t
*
me
);
int
raft_get_last_applied_idx
(
raft_server_t
*
me
);
/**
* @return 1 if node is leader; 0 otherwise */
int
raft_node_is_leader
(
raft_node_t
*
node
);
int
raft_node_is_leader
(
raft_node_t
*
node
);
/**
* @return the node's next index */
int
raft_node_get_next_idx
(
raft_node_t
*
node
);
int
raft_node_get_next_idx
(
raft_node_t
*
node
);
/**
* @param idx The entry's index
* @return entry from index */
raft_entry_t
*
raft_get_entry_from_idx
(
raft_server_t
*
me_
,
int
idx
);
raft_entry_t
*
raft_get_entry_from_idx
(
raft_server_t
*
me_
,
int
idx
);
raft_node_t
*
raft_get_node
(
raft_server_t
*
me_
,
int
nodeid
);
/**
* @param node The node's index
int
raft_get_nodeid
(
raft_server_t
*
me_
);
* @return node pointed to by node index
*/
raft_node_t
*
raft_get_node
(
raft_server_t
*
me_
,
int
node
);
/**
/**
* @return number of votes this server has received this election */
* @return number of votes this server has received this election */
...
...
raft_node.c
View file @
33367594
...
@@ -47,3 +47,9 @@ void raft_node_set_next_idx(raft_node_t* me_, int nextIdx)
...
@@ -47,3 +47,9 @@ void raft_node_set_next_idx(raft_node_t* me_, int nextIdx)
raft_node_private_t
*
me
=
(
void
*
)
me_
;
raft_node_private_t
*
me
=
(
void
*
)
me_
;
me
->
next_idx
=
nextIdx
;
me
->
next_idx
=
nextIdx
;
}
}
void
*
raft_node_get_udata
(
raft_node_t
*
me_
)
{
raft_node_private_t
*
me
=
(
void
*
)
me_
;
return
me
->
udata
;
}
raft_private.h
View file @
33367594
...
@@ -8,7 +8,13 @@
...
@@ -8,7 +8,13 @@
* @version 0.1
* @version 0.1
*/
*/
/* These are here for testing purposes */
enum
{
RAFT_STATE_NONE
,
RAFT_STATE_FOLLOWER
,
RAFT_STATE_CANDIDATE
,
RAFT_STATE_LEADER
};
void
raft_election_start
(
raft_server_t
*
me
);
void
raft_election_start
(
raft_server_t
*
me
);
...
...
raft_server.c
View file @
33367594
...
@@ -510,7 +510,7 @@ int raft_send_entry_response(raft_server_t* me_,
...
@@ -510,7 +510,7 @@ int raft_send_entry_response(raft_server_t* me_,
return
0
;
return
0
;
}
}
int
raft_recv_entry
(
raft_server_t
*
me_
,
int
node
,
msg_entry_t
*
cmd
)
int
raft_recv_entry
(
raft_server_t
*
me_
,
int
node
,
msg_entry_t
*
e
)
{
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_entry_t
ety
;
raft_entry_t
ety
;
...
@@ -519,11 +519,11 @@ int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* cmd)
...
@@ -519,11 +519,11 @@ int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* cmd)
__log
(
me_
,
NULL
,
"received entry from: %d"
,
node
);
__log
(
me_
,
NULL
,
"received entry from: %d"
,
node
);
ety
.
term
=
me
->
current_term
;
ety
.
term
=
me
->
current_term
;
ety
.
id
=
cmd
->
id
;
ety
.
id
=
e
->
id
;
ety
.
data
=
cmd
->
data
;
ety
.
data
=
e
->
data
;
ety
.
len
=
cmd
->
len
;
ety
.
len
=
e
->
len
;
res
=
raft_append_entry
(
me_
,
&
ety
);
res
=
raft_append_entry
(
me_
,
&
ety
);
raft_send_entry_response
(
me_
,
node
,
cmd
->
id
,
res
);
raft_send_entry_response
(
me_
,
node
,
e
->
id
,
res
);
for
(
i
=
0
;
i
<
me
->
nnodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
nnodes
;
i
++
)
{
{
if
(
me
->
nodeid
==
i
)
continue
;
if
(
me
->
nodeid
==
i
)
continue
;
...
@@ -562,8 +562,9 @@ int raft_append_entry(raft_server_t* me_, raft_entry_t* c)
...
@@ -562,8 +562,9 @@ int raft_append_entry(raft_server_t* me_, raft_entry_t* c)
int
raft_apply_entry
(
raft_server_t
*
me_
)
int
raft_apply_entry
(
raft_server_t
*
me_
)
{
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_entry_t
*
e
;
if
(
!
log_get_from_idx
(
me
->
log
,
me
->
last_applied_idx
+
1
))
if
(
!
(
e
=
log_get_from_idx
(
me
->
log
,
me
->
last_applied_idx
+
1
))
)
return
0
;
return
0
;
__log
(
me_
,
NULL
,
"applying log: %d"
,
me
->
last_applied_idx
);
__log
(
me_
,
NULL
,
"applying log: %d"
,
me
->
last_applied_idx
);
...
@@ -571,9 +572,8 @@ int raft_apply_entry(raft_server_t* me_)
...
@@ -571,9 +572,8 @@ int raft_apply_entry(raft_server_t* me_)
me
->
last_applied_idx
++
;
me
->
last_applied_idx
++
;
if
(
me
->
commit_idx
<
me
->
last_applied_idx
)
if
(
me
->
commit_idx
<
me
->
last_applied_idx
)
me
->
commit_idx
=
me
->
last_applied_idx
;
me
->
commit_idx
=
me
->
last_applied_idx
;
if
(
me
->
cb
.
applylog
)
// TODO: callback for state machine application goes here
me
->
cb
.
applylog
(
me
->
cb_ctx
,
me
,
e
->
data
,
e
->
len
);
return
1
;
return
1
;
}
}
...
@@ -612,7 +612,7 @@ void raft_send_appendentries_all(raft_server_t* me_)
...
@@ -612,7 +612,7 @@ void raft_send_appendentries_all(raft_server_t* me_)
}
}
void
raft_set_configuration
(
raft_server_t
*
me_
,
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_node_configuration_t
*
nodes
,
int
m
e
_idx
)
raft_node_configuration_t
*
nodes
,
int
m
y
_idx
)
{
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
nnodes
;
int
nnodes
;
...
@@ -623,10 +623,10 @@ void raft_set_configuration(raft_server_t* me_,
...
@@ -623,10 +623,10 @@ void raft_set_configuration(raft_server_t* me_,
nnodes
++
;
nnodes
++
;
me
->
nodes
=
realloc
(
me
->
nodes
,
sizeof
(
raft_node_t
*
)
*
nnodes
);
me
->
nodes
=
realloc
(
me
->
nodes
,
sizeof
(
raft_node_t
*
)
*
nnodes
);
me
->
nnodes
=
nnodes
;
me
->
nnodes
=
nnodes
;
me
->
nodes
[
nnodes
-
1
]
=
raft_node_new
(
nodes
);
me
->
nodes
[
nnodes
-
1
]
=
raft_node_new
(
nodes
->
udata_address
);
}
}
me
->
votes_for_me
=
calloc
(
nnodes
,
sizeof
(
int
));
me
->
votes_for_me
=
calloc
(
nnodes
,
sizeof
(
int
));
me
->
nodeid
=
m
e
_idx
;
me
->
nodeid
=
m
y
_idx
;
}
}
int
raft_get_nvotes_for_me
(
raft_server_t
*
me_
)
int
raft_get_nvotes_for_me
(
raft_server_t
*
me_
)
...
@@ -647,6 +647,12 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
...
@@ -647,6 +647,12 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
return
votes
;
return
votes
;
}
}
void
raft_vote
(
raft_server_t
*
me_
,
int
node
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
voted_for
=
node
;
}
void
raft_set_election_timeout
(
raft_server_t
*
me_
,
int
millisec
)
void
raft_set_election_timeout
(
raft_server_t
*
me_
,
int
millisec
)
{
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
...
@@ -674,12 +680,6 @@ int raft_get_request_timeout(raft_server_t* me_)
...
@@ -674,12 +680,6 @@ int raft_get_request_timeout(raft_server_t* me_)
return
((
raft_server_private_t
*
)
me_
)
->
request_timeout
;
return
((
raft_server_private_t
*
)
me_
)
->
request_timeout
;
}
}
void
raft_vote
(
raft_server_t
*
me_
,
int
node
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
voted_for
=
node
;
}
int
raft_get_num_nodes
(
raft_server_t
*
me_
)
int
raft_get_num_nodes
(
raft_server_t
*
me_
)
{
{
return
((
raft_server_private_t
*
)
me_
)
->
nnodes
;
return
((
raft_server_private_t
*
)
me_
)
->
nnodes
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment