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
eefa3687
Commit
eefa3687
authored
Jan 25, 2016
by
Willem Thiart
Browse files
Change voted_for to int
parent
9f79cca3
Changes
5
Hide whitespace changes
Inline
Side-by-side
include/raft.h
View file @
eefa3687
...
@@ -564,6 +564,11 @@ int raft_get_my_id(raft_server_t* me);
...
@@ -564,6 +564,11 @@ int raft_get_my_id(raft_server_t* me);
* @param[in] node The server to vote for */
* @param[in] node The server to vote for */
void
raft_vote
(
raft_server_t
*
me_
,
raft_node_t
*
node
);
void
raft_vote
(
raft_server_t
*
me_
,
raft_node_t
*
node
);
/** Vote for a server.
* This should be used to reload persistent state, ie. the voted-for field.
* @param[in] nodeid The server to vote for by nodeid */
void
raft_vote_for_nodeid
(
raft_server_t
*
me_
,
const
int
nodeid
);
/** Set the current term.
/** Set the current term.
* This should be used to reload persistent state, ie. the current_term field.
* This should be used to reload persistent state, ie. the current_term field.
* @param[in] term The new current term */
* @param[in] term The new current term */
...
...
include/raft_private.h
View file @
eefa3687
...
@@ -21,7 +21,7 @@ typedef struct {
...
@@ -21,7 +21,7 @@ typedef struct {
/* The candidate the server voted for in its current term,
/* The candidate the server voted for in its current term,
* or Nil if it hasn't voted for any. */
* or Nil if it hasn't voted for any. */
raft_node_t
*
voted_for
;
int
voted_for
;
/* the log which is replicated */
/* the log which is replicated */
void
*
log
;
void
*
log
;
...
...
src/raft_server.c
View file @
eefa3687
...
@@ -44,7 +44,7 @@ raft_server_t* raft_new()
...
@@ -44,7 +44,7 @@ raft_server_t* raft_new()
if
(
!
me
)
if
(
!
me
)
return
NULL
;
return
NULL
;
me
->
current_term
=
0
;
me
->
current_term
=
0
;
me
->
voted_for
=
NULL
;
me
->
voted_for
=
-
1
;
me
->
timeout_elapsed
=
0
;
me
->
timeout_elapsed
=
0
;
me
->
request_timeout
=
200
;
me
->
request_timeout
=
200
;
me
->
election_timeout
=
1000
;
me
->
election_timeout
=
1000
;
...
@@ -289,7 +289,7 @@ int raft_recv_appendentries(
...
@@ -289,7 +289,7 @@ int raft_recv_appendentries(
if
(
raft_is_candidate
(
me_
)
&&
me
->
current_term
==
ae
->
term
)
if
(
raft_is_candidate
(
me_
)
&&
me
->
current_term
==
ae
->
term
)
{
{
me
->
voted_for
=
NULL
;
me
->
voted_for
=
-
1
;
raft_become_follower
(
me_
);
raft_become_follower
(
me_
);
}
}
else
if
(
me
->
current_term
<
ae
->
term
)
else
if
(
me
->
current_term
<
ae
->
term
)
...
@@ -403,7 +403,7 @@ static int __should_grant_vote(raft_server_private_t* me, msg_requestvote_t* vr)
...
@@ -403,7 +403,7 @@ static int __should_grant_vote(raft_server_private_t* me, msg_requestvote_t* vr)
/* TODO: if voted for is candiate return 1 (if below checks pass) */
/* TODO: if voted for is candiate return 1 (if below checks pass) */
/* we've already voted */
/* we've already voted */
if
(
me
->
voted_for
)
if
(
0
<
me
->
voted_for
)
return
0
;
return
0
;
int
current_idx
=
raft_get_current_idx
((
void
*
)
me
);
int
current_idx
=
raft_get_current_idx
((
void
*
)
me
);
...
@@ -428,9 +428,6 @@ int raft_recv_requestvote(raft_server_t* me_,
...
@@ -428,9 +428,6 @@ int raft_recv_requestvote(raft_server_t* me_,
{
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
assert
(
node
);
assert
(
node
!=
me
->
node
);
if
(
raft_get_current_term
(
me_
)
<
vr
->
term
)
if
(
raft_get_current_term
(
me_
)
<
vr
->
term
)
{
{
raft_set_current_term
(
me_
,
vr
->
term
);
raft_set_current_term
(
me_
,
vr
->
term
);
...
@@ -443,7 +440,7 @@ int raft_recv_requestvote(raft_server_t* me_,
...
@@ -443,7 +440,7 @@ int raft_recv_requestvote(raft_server_t* me_,
* Both states would have voted for themselves */
* Both states would have voted for themselves */
assert
(
!
(
raft_is_leader
(
me_
)
||
raft_is_candidate
(
me_
)));
assert
(
!
(
raft_is_leader
(
me_
)
||
raft_is_candidate
(
me_
)));
raft_vote
(
me_
,
node
);
raft_vote
_for_nodeid
(
me_
,
vr
->
candidate_id
);
r
->
vote_granted
=
1
;
r
->
vote_granted
=
1
;
/* there must be in an election. */
/* there must be in an election. */
...
@@ -475,9 +472,6 @@ int raft_recv_requestvote_response(raft_server_t* me_,
...
@@ -475,9 +472,6 @@ int raft_recv_requestvote_response(raft_server_t* me_,
{
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
assert
(
node
);
assert
(
node
!=
me
->
node
);
__log
(
me_
,
node
,
"node responded to requestvote status: %s"
,
__log
(
me_
,
node
,
"node responded to requestvote status: %s"
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
...
@@ -506,7 +500,8 @@ int raft_recv_requestvote_response(raft_server_t* me_,
...
@@ -506,7 +500,8 @@ int raft_recv_requestvote_response(raft_server_t* me_,
if
(
1
==
r
->
vote_granted
)
if
(
1
==
r
->
vote_granted
)
{
{
raft_node_vote_for_me
(
node
,
1
);
if
(
node
)
raft_node_vote_for_me
(
node
,
1
);
int
votes
=
raft_get_nvotes_for_me
(
me_
);
int
votes
=
raft_get_nvotes_for_me
(
me_
);
if
(
raft_votes_is_majority
(
me
->
num_nodes
,
votes
))
if
(
raft_votes_is_majority
(
me
->
num_nodes
,
votes
))
raft_become_leader
(
me_
);
raft_become_leader
(
me_
);
...
@@ -729,7 +724,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
...
@@ -729,7 +724,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
if
(
raft_node_has_vote_for_me
(
me
->
nodes
[
i
]))
if
(
raft_node_has_vote_for_me
(
me
->
nodes
[
i
]))
votes
+=
1
;
votes
+=
1
;
if
(
me
->
voted_for
==
me
->
node
)
if
(
me
->
voted_for
==
raft_get_nodeid
(
me_
)
)
votes
+=
1
;
votes
+=
1
;
return
votes
;
return
votes
;
...
@@ -737,13 +732,16 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
...
@@ -737,13 +732,16 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
void
raft_vote
(
raft_server_t
*
me_
,
raft_node_t
*
node
)
void
raft_vote
(
raft_server_t
*
me_
,
raft_node_t
*
node
)
{
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
raft_vote_for_nodeid
(
me_
,
node
?
raft_node_get_id
(
node
)
:
-
1
);
}
assert
(
!
me
->
voted_for
||
node
!=
me
->
voted_for
);
void
raft_vote_for_nodeid
(
raft_server_t
*
me_
,
const
int
nodeid
)
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
me
->
voted_for
=
node
;
me
->
voted_for
=
node
id
;
if
(
me
->
cb
.
persist_vote
)
if
(
me
->
cb
.
persist_vote
)
me
->
cb
.
persist_vote
(
me_
,
me
->
udata
,
raft_node_get_id
(
node
)
);
me
->
cb
.
persist_vote
(
me_
,
me
->
udata
,
nodeid
);
}
}
int
raft_msg_entry_response_committed
(
raft_server_t
*
me_
,
int
raft_msg_entry_response_committed
(
raft_server_t
*
me_
,
...
...
src/raft_server_properties.c
View file @
eefa3687
...
@@ -66,9 +66,7 @@ int raft_get_log_count(raft_server_t* me_)
...
@@ -66,9 +66,7 @@ int raft_get_log_count(raft_server_t* me_)
int
raft_get_voted_for
(
raft_server_t
*
me_
)
int
raft_get_voted_for
(
raft_server_t
*
me_
)
{
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
if
(
me
->
voted_for
)
return
me
->
voted_for
;
return
raft_node_get_id
(
me
->
voted_for
);
return
-
1
;
}
}
void
raft_set_current_term
(
raft_server_t
*
me_
,
const
int
term
)
void
raft_set_current_term
(
raft_server_t
*
me_
,
const
int
term
)
...
@@ -77,7 +75,7 @@ void raft_set_current_term(raft_server_t* me_, const int term)
...
@@ -77,7 +75,7 @@ void raft_set_current_term(raft_server_t* me_, const int term)
if
(
me
->
current_term
<
term
)
if
(
me
->
current_term
<
term
)
{
{
me
->
current_term
=
term
;
me
->
current_term
=
term
;
me
->
voted_for
=
NULL
;
me
->
voted_for
=
-
1
;
if
(
me
->
cb
.
persist_term
)
if
(
me
->
cb
.
persist_term
)
me
->
cb
.
persist_term
(
me_
,
me
->
udata
,
term
);
me
->
cb
.
persist_term
(
me_
,
me
->
udata
,
term
);
}
}
...
...
tests/test_server.c
View file @
eefa3687
...
@@ -594,6 +594,7 @@ void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than
...
@@ -594,6 +594,7 @@ void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than
/* current term is less than term */
/* current term is less than term */
msg_requestvote_t
rv
;
msg_requestvote_t
rv
;
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
rv
.
candidate_id
=
2
;
rv
.
term
=
2
;
rv
.
term
=
2
;
rv
.
last_log_idx
=
1
;
rv
.
last_log_idx
=
1
;
msg_requestvote_response_t
rvr
;
msg_requestvote_response_t
rvr
;
...
@@ -603,6 +604,30 @@ void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than
...
@@ -603,6 +604,30 @@ void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than
CuAssertIntEquals
(
tc
,
2
,
raft_get_voted_for
(
r
));
CuAssertIntEquals
(
tc
,
2
,
raft_get_voted_for
(
r
));
}
}
void
TestRaft_server_recv_requestvote_depends_on_candidate_id
(
CuTest
*
tc
)
{
void
*
r
=
raft_new
();
raft_add_node
(
r
,
NULL
,
1
,
1
);
raft_add_node
(
r
,
NULL
,
2
,
0
);
raft_become_candidate
(
r
);
raft_set_current_term
(
r
,
1
);
CuAssertIntEquals
(
tc
,
1
,
raft_get_voted_for
(
r
));
/* current term is less than term */
msg_requestvote_t
rv
;
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
rv
.
candidate_id
=
3
;
rv
.
term
=
2
;
rv
.
last_log_idx
=
1
;
msg_requestvote_response_t
rvr
;
raft_recv_requestvote
(
r
,
NULL
,
&
rv
,
&
rvr
);
CuAssertIntEquals
(
tc
,
1
,
raft_is_follower
(
r
));
CuAssertIntEquals
(
tc
,
2
,
raft_get_current_term
(
r
));
CuAssertIntEquals
(
tc
,
3
,
raft_get_voted_for
(
r
));
}
/* If votedFor is null or candidateId, and candidate's log is at
/* If votedFor is null or candidateId, and candidate's log is at
* least as up-to-date as local log, grant vote (5.2, 5.4) */
* least as up-to-date as local log, grant vote (5.2, 5.4) */
void
TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate
(
void
TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate
(
...
...
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