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
1297265f
Commit
1297265f
authored
Nov 12, 2015
by
Willem Thiart
Browse files
Add better logging; Fix leader election failure
parent
f123874b
Changes
4
Hide whitespace changes
Inline
Side-by-side
include/raft.h
View file @
1297265f
...
...
@@ -173,12 +173,14 @@ typedef int (
/** Callback for providing debug logging information.
* This callback is optional
* @param[in] raft The Raft server making this callback
* @param[in] node The node that is the subject of this log. Could be NULL.
* @param[in] user_data User data that is passed from Raft server
* @param[in] buf The buffer that was logged */
typedef
void
(
*
func_log_f
)
(
raft_server_t
*
raft
,
raft_node_t
*
node
,
void
*
user_data
,
const
char
*
buf
);
...
...
@@ -563,4 +565,12 @@ int raft_get_state(raft_server_t* me_);
* @return the last log term */
int
raft_get_last_log_term
(
raft_server_t
*
me_
);
/** Tell if we are a leader, candidate or follower.
* @return get state of type raft_state_e. */
int
raft_get_state
(
raft_server_t
*
me_
);
/** The the most recent log's term
* @return the last log term */
int
raft_get_last_log_term
(
raft_server_t
*
me_
);
#endif
/* RAFT_H_ */
src/raft_server.c
View file @
1297265f
...
...
@@ -24,7 +24,7 @@
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) < (b) ? (b) : (a))
static
void
__log
(
raft_server_t
*
me_
,
const
char
*
fmt
,
...)
static
void
__log
(
raft_server_t
*
me_
,
raft_node_t
*
node
,
const
char
*
fmt
,
...)
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
char
buf
[
1024
];
...
...
@@ -34,7 +34,7 @@ static void __log(raft_server_t *me_, const char *fmt, ...)
vsprintf
(
buf
,
fmt
,
args
);
if
(
me
->
cb
.
log
)
me
->
cb
.
log
(
me_
,
me
->
udata
,
buf
);
me
->
cb
.
log
(
me_
,
node
,
me
->
udata
,
buf
);
}
raft_server_t
*
raft_new
()
...
...
@@ -75,8 +75,9 @@ void raft_election_start(raft_server_t* me_)
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
__log
(
me_
,
"election starting: %d %d, term: %d"
,
me
->
election_timeout
,
me
->
timeout_elapsed
,
me
->
current_term
);
__log
(
me_
,
NULL
,
"election starting: %d %d, term: %d ci: %d"
,
me
->
election_timeout
,
me
->
timeout_elapsed
,
me
->
current_term
,
raft_get_current_idx
(
me_
));
raft_become_candidate
(
me_
);
}
...
...
@@ -86,7 +87,7 @@ void raft_become_leader(raft_server_t* me_)
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
;
__log
(
me_
,
"becoming leader
"
);
__log
(
me_
,
NULL
,
"becoming leader
term:%d"
,
raft_get_current_term
(
me_
)
);
raft_set_state
(
me_
,
RAFT_STATE_LEADER
);
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
...
...
@@ -106,11 +107,11 @@ void raft_become_candidate(raft_server_t* me_)
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
;
__log
(
me_
,
"becoming candidate"
);
__log
(
me_
,
NULL
,
"becoming candidate"
);
raft_set_current_term
(
me_
,
raft_get_current_term
(
me_
)
+
1
);
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
raft_node_vote_for_me
(
me
->
nodes
[
i
],
0
);
me
->
current_term
+=
1
;
raft_vote
(
me_
,
me
->
node
);
me
->
current_leader
=
NULL
;
raft_set_state
(
me_
,
RAFT_STATE_CANDIDATE
);
...
...
@@ -126,7 +127,7 @@ void raft_become_candidate(raft_server_t* me_)
void
raft_become_follower
(
raft_server_t
*
me_
)
{
__log
(
me_
,
"becoming follower"
);
__log
(
me_
,
NULL
,
"becoming follower"
);
raft_set_state
(
me_
,
RAFT_STATE_FOLLOWER
);
}
...
...
@@ -171,9 +172,11 @@ int raft_recv_appendentries_response(raft_server_t* me_,
assert
(
node
);
assert
(
node
!=
me
->
node
);
__log
(
me_
,
"received appendentries response node: %d %s cidx: %d 1stidx: %d"
,
node
,
r
->
success
==
1
?
"success"
:
"fail"
,
r
->
current_idx
,
__log
(
me_
,
node
,
"received appendentries response %s ci:%d rci:%d 1stidx:%d"
,
r
->
success
==
1
?
"SUCCESS"
:
"fail"
,
raft_get_current_idx
(
me_
),
r
->
current_idx
,
r
->
first_idx
);
if
(
!
raft_is_leader
(
me_
))
...
...
@@ -263,9 +266,10 @@ int raft_recv_appendentries(
me
->
timeout_elapsed
=
0
;
if
(
0
<
ae
->
n_entries
)
__log
(
me_
,
"recvd appendentries from: %
d, %d %d %d
%d #%d"
,
__log
(
me_
,
node
,
"recvd appendentries from: %
lx, t:%d ci:%d lc:%d pli:%d plt:
%d #%d"
,
node
,
ae
->
term
,
raft_get_current_idx
(
me_
),
ae
->
leader_commit
,
ae
->
prev_log_idx
,
ae
->
prev_log_term
,
...
...
@@ -286,7 +290,8 @@ int raft_recv_appendentries(
else
if
(
ae
->
term
<
me
->
current_term
)
{
/* 1. Reply false if term < currentTerm (§5.1) */
__log
(
me_
,
"AE term is less than current term"
);
__log
(
me_
,
node
,
"AE term %d is less than current term %d"
,
ae
->
term
,
me
->
current_term
);
goto
fail_with_current_idx
;
}
...
...
@@ -298,7 +303,7 @@ int raft_recv_appendentries(
if
(
!
e
)
{
__log
(
me_
,
"AE no log at prev_idx %d"
,
ae
->
prev_log_idx
);
__log
(
me_
,
node
,
"AE no log at prev_idx %d"
,
ae
->
prev_log_idx
);
goto
fail_with_current_idx
;
}
...
...
@@ -309,8 +314,8 @@ int raft_recv_appendentries(
if
(
e
->
term
!=
ae
->
prev_log_term
)
{
__log
(
me_
,
"AE term doesn't match prev_
idx
(ie. %d vs %d)"
,
e
->
term
,
ae
->
prev_log_term
);
__log
(
me_
,
node
,
"AE term doesn't match prev_
term
(ie. %d vs %d)
ci:%d pli:%d
"
,
e
->
term
,
ae
->
prev_log_term
,
raft_get_current_idx
(
me_
),
ae
->
prev_log_idx
);
assert
(
me
->
commit_idx
<
ae
->
prev_log_idx
);
/* Delete all the following log entries because they don't match */
log_delete
(
me
->
log
,
ae
->
prev_log_idx
);
...
...
@@ -438,7 +443,7 @@ int raft_recv_requestvote(raft_server_t* me_,
else
r
->
vote_granted
=
0
;
__log
(
me_
,
"node requested vote: %d replying: %s"
,
__log
(
me_
,
node
,
"node requested vote: %d replying: %s"
,
node
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
r
->
term
=
raft_get_current_term
(
me_
);
...
...
@@ -462,8 +467,8 @@ int raft_recv_requestvote_response(raft_server_t* me_,
assert
(
node
);
assert
(
node
!=
me
->
node
);
__log
(
me_
,
"node responded to requestvote
: %d
status: %s"
,
node
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
__log
(
me_
,
node
,
"node responded to requestvote status: %s"
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
if
(
!
raft_is_candidate
(
me_
))
return
0
;
...
...
@@ -482,6 +487,11 @@ int raft_recv_requestvote_response(raft_server_t* me_,
return
0
;
}
__log
(
me_
,
node
,
"node responded to requestvote: %d status: %s ct:%d rt:%d"
,
node
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
,
me
->
current_term
,
r
->
term
);
if
(
1
==
r
->
vote_granted
)
{
raft_node_vote_for_me
(
node
,
1
);
...
...
@@ -502,7 +512,8 @@ int raft_recv_entry(raft_server_t* me_, raft_node_t* node, msg_entry_t* e,
if
(
!
raft_is_leader
(
me_
))
return
-
1
;
__log
(
me_
,
"received entry from: %d"
,
node
);
__log
(
me_
,
node
,
"received entry t:%d id: %d idx: %d"
,
me
->
current_term
,
e
->
id
,
raft_get_current_idx
(
me_
)
+
1
,
node
);
raft_entry_t
ety
;
ety
.
term
=
me
->
current_term
;
...
...
@@ -538,7 +549,7 @@ int raft_send_requestvote(raft_server_t* me_, raft_node_t* node)
assert
(
node
);
assert
(
node
!=
me
->
node
);
__log
(
me_
,
"sending requestvote to: %d"
,
node
);
__log
(
me_
,
node
,
"sending requestvote to: %d"
,
node
);
rv
.
term
=
me
->
current_term
;
rv
.
last_log_idx
=
raft_get_current_idx
(
me_
);
...
...
@@ -567,7 +578,8 @@ int raft_apply_entry(raft_server_t* me_)
if
(
!
e
)
return
-
1
;
__log
(
me_
,
"applying log: %d, size: %d"
,
me
->
last_applied_idx
,
e
->
data
.
len
);
__log
(
me_
,
NULL
,
"applying log: %d, id: %d size: %d"
,
me
->
last_applied_idx
,
e
->
id
,
e
->
data
.
len
);
me
->
last_applied_idx
++
;
if
(
me
->
cb
.
applylog
)
...
...
@@ -618,12 +630,12 @@ int raft_send_appendentries(raft_server_t* me_, raft_node_t* node)
ae
.
prev_log_term
=
prev_ety
->
term
;
}
__log
(
me_
,
"sending appendentries node:
%d, %d %d %d
%d"
,
node
,
ae
.
term
,
ae
.
leader_commit
,
ae
.
prev_log_idx
,
ae
.
prev_log_term
);
__log
(
me_
,
node
,
"sending appendentries node:
ci:%d t:%d lc:%d pli:%d plt:
%d"
,
raft_get_current_idx
(
me_
)
,
ae
.
term
,
ae
.
leader_commit
,
ae
.
prev_log_idx
,
ae
.
prev_log_term
);
me
->
cb
.
send_appendentries
(
me_
,
me
->
udata
,
node
,
&
ae
);
...
...
@@ -680,6 +692,8 @@ void raft_vote(raft_server_t* me_, raft_node_t* node)
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
assert
(
!
me
->
voted_for
||
node
!=
me
->
voted_for
);
me
->
voted_for
=
node
;
if
(
me
->
cb
.
persist_vote
)
me
->
cb
.
persist_vote
(
me_
,
me
->
udata
,
raft_node_get_id
(
node
));
...
...
src/raft_server_properties.c
View file @
1297265f
...
...
@@ -137,7 +137,7 @@ raft_node_t* raft_get_node(raft_server_t *me_, int nodeid)
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
if
(
nodeid
==
raft_node_get_id
(
me
->
nodes
[
i
]))
return
me
->
nodes
[
i
];
...
...
tests/test_server.c
View file @
1297265f
...
...
@@ -1141,6 +1141,7 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(
ety
.
data
.
buf
=
(
unsigned
char
*
)
"aaa"
;
raft_append_entry
(
r
,
&
ety
);
ety
.
id
=
101
;
ety
.
term
=
2
;
raft_append_entry
(
r
,
&
ety
);
/* vote not granted */
...
...
@@ -1153,9 +1154,9 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(
rv
.
term
=
2
;
rv
.
candidate_id
=
1
;
rv
.
last_log_idx
=
1
;
rv
.
last_log_term
=
2
;
rv
.
last_log_term
=
3
;
raft_recv_requestvote
(
r
,
raft_get_node
(
r
,
2
),
&
rv
,
&
rvr
);
CuAssert
True
(
tc
,
1
==
rvr
.
vote_granted
);
CuAssert
IntEquals
(
tc
,
1
,
rvr
.
vote_granted
);
}
void
TestRaft_candidate_becomes_candidate_is_candidate
(
CuTest
*
tc
)
...
...
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