Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Willemt Raft
Commits
9556f4ee
Commit
9556f4ee
authored
Jan 16, 2014
by
willem
Browse files
term defaults to 0 test case
parent
c36ad399
Changes
5
Hide whitespace changes
Inline
Side-by-side
include/raft.h
View file @
9556f4ee
...
...
@@ -151,12 +151,15 @@ typedef struct {
/* length of entry data */
unsigned
int
len
;
/* number of nodes that have this entry */
unsigned
int
nnodes
;
unsigned
int
n
um_
nodes
;
}
raft_entry_t
;
/**
* Initialise a new raft server
* Election timeout defaults to 1000 milliseconds */
*
* Request timeout defaults to 200 milliseconds
* Election timeout defaults to 1000 milliseconds
* @return newly initialised raft server */
raft_server_t
*
raft_new
();
/**
...
...
raft_log.c
View file @
9556f4ee
...
...
@@ -96,7 +96,7 @@ int log_append_entry(log_t* me_, raft_entry_t* c)
// return 0;
memcpy
(
&
me
->
entries
[
me
->
back
],
c
,
sizeof
(
raft_entry_t
));
me
->
entries
[
me
->
back
].
nnodes
=
0
;
me
->
entries
[
me
->
back
].
n
um_
nodes
=
0
;
me
->
count
++
;
me
->
back
++
;
return
1
;
...
...
@@ -216,7 +216,7 @@ void log_mark_node_has_committed(log_t* me_, int idx)
if
((
e
=
log_get_from_idx
(
me_
,
idx
)))
{
e
->
nnodes
+=
1
;
e
->
n
um_
nodes
+=
1
;
}
}
raft_server.c
View file @
9556f4ee
...
...
@@ -22,32 +22,6 @@
#include "raft_private.h"
#include "raft_log.h"
typedef
struct
{
/* Array: For each server, index of the next log entry to send to
* that server (initialized to leader last log index +1) */
int
next_index
;
/* Array: for each server, index of highest log entry known to be
* replicated on server (initialized to 0, increases monotonically) */
int
match_index
;
/* The latest entry that each follower has acknowledged is the same as
* the leader's. This is used to calculate commitIndex on the leader. */
int
last_agree_index
;
}
leader_t
;
typedef
struct
{
/* The set of servers from which the candidate has
* received a RequestVote response in this term. */
int
votes_responded
;
/* The set of servers from which the candidate has received a vote in this
* term. */
int
votes_granted
;
}
candidate_t
;
typedef
struct
{
/* Persistent state: */
...
...
@@ -79,11 +53,11 @@ typedef struct {
/* amount of time left till timeout */
int
timeout_elapsed
;
/* who has voted for me. This is an array with N = 'nnodes' elements */
/* who has voted for me. This is an array with N = 'n
um_
nodes' elements */
int
*
votes_for_me
;
raft_node_t
*
nodes
;
int
nnodes
;
int
n
um_
nodes
;
int
election_timeout
;
int
request_timeout
;
...
...
@@ -95,11 +69,6 @@ typedef struct {
/* my node ID */
int
nodeid
;
union
{
leader_t
leader
;
candidate_t
candidate
;
};
}
raft_server_private_t
;
static
void
__log
(
raft_server_t
*
me_
,
void
*
src
,
const
char
*
fmt
,
...)
...
...
@@ -121,14 +90,14 @@ raft_server_t* raft_new()
if
(
!
(
me
=
calloc
(
1
,
sizeof
(
raft_server_private_t
))))
return
NULL
;
me
->
current_term
=
1
;
me
->
current_term
=
0
;
me
->
voted_for
=
-
1
;
me
->
current_idx
=
1
;
me
->
timeout_elapsed
=
0
;
me
->
log
=
log_new
();
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
me
->
request_timeout
=
200
;
me
->
election_timeout
=
1000
;
me
->
log
=
log_new
();
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
return
(
void
*
)
me
;
}
...
...
@@ -166,7 +135,7 @@ void raft_become_leader(raft_server_t* me_)
__log
(
me_
,
NULL
,
"becoming leader"
);
raft_set_state
(
me_
,
RAFT_STATE_LEADER
);
me
->
voted_for
=
-
1
;
for
(
i
=
0
;
i
<
me
->
nnodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
n
um_
nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
raft_node_t
*
p
=
raft_get_node
(
me_
,
i
);
...
...
@@ -181,13 +150,13 @@ void raft_become_candidate(raft_server_t* me_)
int
i
;
__log
(
me_
,
NULL
,
"becoming candidate"
);
memset
(
me
->
votes_for_me
,
0
,
sizeof
(
int
)
*
me
->
nnodes
);
memset
(
me
->
votes_for_me
,
0
,
sizeof
(
int
)
*
me
->
n
um_
nodes
);
me
->
current_term
+=
1
;
raft_vote
(
me_
,
me
->
nodeid
);
raft_set_state
(
me_
,
RAFT_STATE_CANDIDATE
);
me
->
timeout_elapsed
=
rand
()
%
500
;
/* request votes from nodes */
for
(
i
=
0
;
i
<
me
->
nnodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
n
um_
nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_requestvote
(
me_
,
i
);
...
...
@@ -271,7 +240,7 @@ int raft_recv_appendentries_response(raft_server_t* me_,
e
=
log_get_from_idx
(
me
->
log
,
me
->
last_applied_idx
+
1
);
/* majority has this */
if
(
e
&&
me
->
nnodes
/
2
<=
e
->
nnodes
)
if
(
e
&&
me
->
n
um_
nodes
/
2
<=
e
->
n
um_
nodes
)
{
if
(
0
==
raft_apply_entry
(
me_
))
break
;
}
...
...
@@ -455,13 +424,13 @@ int raft_recv_requestvote(raft_server_t* me_, int node, msg_requestvote_t* vr)
return
0
;
}
int
raft_votes_is_majority
(
const
int
nnodes
,
const
int
nvotes
)
int
raft_votes_is_majority
(
const
int
n
um_
nodes
,
const
int
nvotes
)
{
int
half
;
if
(
nnodes
<
nvotes
)
if
(
n
um_
nodes
<
nvotes
)
return
0
;
half
=
nnodes
/
2
;
half
=
n
um_
nodes
/
2
;
return
half
+
1
<=
nvotes
;
}
...
...
@@ -476,7 +445,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node,
if
(
raft_is_leader
(
me_
))
return
0
;
assert
(
node
<
me
->
nnodes
);
assert
(
node
<
me
->
n
um_
nodes
);
// if (r->term != raft_get_current_term(me_))
// return 0;
...
...
@@ -487,7 +456,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node,
me
->
votes_for_me
[
node
]
=
1
;
votes
=
raft_get_nvotes_for_me
(
me_
);
if
(
raft_votes_is_majority
(
me
->
nnodes
,
votes
))
if
(
raft_votes_is_majority
(
me
->
n
um_
nodes
,
votes
))
raft_become_leader
(
me_
);
}
...
...
@@ -524,7 +493,7 @@ int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* e)
ety
.
len
=
e
->
len
;
res
=
raft_append_entry
(
me_
,
&
ety
);
raft_send_entry_response
(
me_
,
node
,
e
->
id
,
res
);
for
(
i
=
0
;
i
<
me
->
nnodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
n
um_
nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_appendentries
(
me_
,
i
);
...
...
@@ -604,7 +573,7 @@ void raft_send_appendentries_all(raft_server_t* me_)
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
i
;
for
(
i
=
0
;
i
<
me
->
nnodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
n
um_
nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_appendentries
(
me_
,
i
);
...
...
@@ -615,17 +584,17 @@ void raft_set_configuration(raft_server_t* me_,
raft_node_configuration_t
*
nodes
,
int
my_idx
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
nnodes
;
int
n
um_
nodes
;
/* TODO: one memory allocation only please */
for
(
nnodes
=
0
;
nodes
->
udata_address
;
nodes
++
)
for
(
n
um_
nodes
=
0
;
nodes
->
udata_address
;
nodes
++
)
{
nnodes
++
;
me
->
nodes
=
realloc
(
me
->
nodes
,
sizeof
(
raft_node_t
*
)
*
nnodes
);
me
->
nnodes
=
nnodes
;
me
->
nodes
[
nnodes
-
1
]
=
raft_node_new
(
nodes
->
udata_address
);
n
um_
nodes
++
;
me
->
nodes
=
realloc
(
me
->
nodes
,
sizeof
(
raft_node_t
*
)
*
n
um_
nodes
);
me
->
n
um_
nodes
=
n
um_
nodes
;
me
->
nodes
[
n
um_
nodes
-
1
]
=
raft_node_new
(
nodes
->
udata_address
);
}
me
->
votes_for_me
=
calloc
(
nnodes
,
sizeof
(
int
));
me
->
votes_for_me
=
calloc
(
n
um_
nodes
,
sizeof
(
int
));
me
->
nodeid
=
my_idx
;
}
...
...
@@ -634,7 +603,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
i
,
votes
;
for
(
i
=
0
,
votes
=
0
;
i
<
me
->
nnodes
;
i
++
)
for
(
i
=
0
,
votes
=
0
;
i
<
me
->
n
um_
nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
if
(
1
==
me
->
votes_for_me
[
i
])
...
...
@@ -682,14 +651,14 @@ int raft_get_request_timeout(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_
)
->
n
um_
nodes
;
}
raft_node_t
*
raft_get_node
(
raft_server_t
*
me_
,
int
nodeid
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
if
(
nodeid
<
0
||
me
->
nnodes
<=
nodeid
)
if
(
nodeid
<
0
||
me
->
n
um_
nodes
<=
nodeid
)
return
NULL
;
return
me
->
nodes
[
nodeid
];
}
...
...
tests/test_log.c
View file @
9556f4ee
...
...
@@ -68,11 +68,11 @@ void TestLog_mark_node_has_committed_adds_nodes(CuTest * tc)
l
=
log_new
();
e1
.
id
=
1
;
log_append_entry
(
l
,
&
e1
);
CuAssertTrue
(
tc
,
0
==
log_get_from_idx
(
l
,
1
)
->
nnodes
);
CuAssertTrue
(
tc
,
0
==
log_get_from_idx
(
l
,
1
)
->
n
um_
nodes
);
log_mark_node_has_committed
(
l
,
1
);
CuAssertTrue
(
tc
,
1
==
log_get_from_idx
(
l
,
1
)
->
nnodes
);
CuAssertTrue
(
tc
,
1
==
log_get_from_idx
(
l
,
1
)
->
n
um_
nodes
);
log_mark_node_has_committed
(
l
,
1
);
CuAssertTrue
(
tc
,
2
==
log_get_from_idx
(
l
,
1
)
->
nnodes
);
CuAssertTrue
(
tc
,
2
==
log_get_from_idx
(
l
,
1
)
->
n
um_
nodes
);
}
void
TestLog_delete
(
CuTest
*
tc
)
...
...
tests/test_server.c
View file @
9556f4ee
...
...
@@ -30,12 +30,19 @@ void TestRaft_server_idx_starts_at_1(CuTest * tc)
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
}
void
TestRaft_server_currentterm_defaults_to_0
(
CuTest
*
tc
)
{
void
*
r
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_term
(
r
));
}
void
TestRaft_server_set_currentterm_sets_term
(
CuTest
*
tc
)
{
void
*
r
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
1
==
raft_get_current_term
(
r
));
raft_set_current_term
(
r
,
5
);
CuAssertTrue
(
tc
,
5
==
raft_get_current_term
(
r
));
}
...
...
@@ -1155,9 +1162,9 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc)
r
=
raft_new
();
CuAssertTrue
(
tc
,
1
==
raft_get_current_term
(
r
));
CuAssertTrue
(
tc
,
0
==
raft_get_current_term
(
r
));
raft_become_candidate
(
r
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_term
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_current_term
(
r
));
}
/* Candidate 5.2 */
...
...
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