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
RedisLabs Raft
Commits
e4c4029e
Commit
e4c4029e
authored
Nov 06, 2015
by
Willem Thiart
Browse files
Prevent dupe entries
Thanks to @ar104 for help with this fix!
parent
591973e3
Changes
2
Show whitespace changes
Inline
Side-by-side
src/raft_server.c
View file @
e4c4029e
...
...
@@ -283,18 +283,27 @@ int raft_recv_appendentries(
/* 3. If an existing entry conflicts with a new one (same index
but different terms), delete the existing entry and all that
follow it (§5.3) */
int
has_mismatch
=
0
,
i
;
int
i
;
for
(
i
=
0
;
i
<
ae
->
n_entries
;
i
++
)
{
msg_entry_t
*
cmd
=
&
ae
->
entries
[
i
];
int
index
=
ae
->
prev_log_idx
+
1
+
i
;
raft_entry_t
*
e2
=
raft_get_entry_from_idx
(
me_
,
index
);
if
(
!
e2
)
break
;
/* reached end of log */
if
(
e2
&&
e2
->
term
!=
cmd
->
term
)
has_mismatch
=
1
;
if
(
has_mismatch
)
log_delete
(
me
->
log
,
index
);
msg_entry_t
*
ety
=
&
ae
->
entries
[
i
];
int
ety_index
=
ae
->
prev_log_idx
+
1
+
i
;
raft_entry_t
*
existing_ety
=
raft_get_entry_from_idx
(
me_
,
ety_index
);
if
(
existing_ety
&&
existing_ety
->
term
!=
ety
->
term
)
{
log_delete
(
me
->
log
,
ety_index
);
break
;
}
else
if
(
!
existing_ety
)
break
;
}
/* Pick up remainder in case of mismatch or missing existing entry */
for
(;
i
<
ae
->
n_entries
;
i
++
)
{
int
e
=
raft_append_entry
(
me_
,
&
ae
->
entries
[
i
]);
if
(
-
1
==
e
)
goto
fail
;
}
/* 4. If leaderCommit > commitIndex, set commitIndex =
...
...
@@ -309,31 +318,19 @@ int raft_recv_appendentries(
raft_become_follower
(
me_
);
raft_set_current_term
(
me_
,
ae
->
term
);
/* update current leader because we accepted appendentries from it */
me
->
current_leader
=
node
;
/* append all entries to log */
for
(
i
=
0
;
i
<
ae
->
n_entries
;
i
++
)
{
msg_entry_t
*
cmd
=
&
ae
->
entries
[
i
];
raft_entry_t
ety
;
ety
.
term
=
cmd
->
term
;
ety
.
id
=
cmd
->
id
;
memcpy
(
&
ety
.
data
,
&
cmd
->
data
,
sizeof
(
raft_entry_data_t
));
int
e
=
raft_append_entry
(
me_
,
&
ety
);
if
(
-
1
==
e
)
{
__log
(
me_
,
"AE failure; couldn't append entry"
);
r
->
success
=
0
;
return
-
1
;
}
}
r
->
success
=
1
;
r
->
current_idx
=
raft_get_current_idx
(
me_
);
r
->
first_idx
=
ae
->
prev_log_idx
+
1
;
return
0
;
fail:
__log
(
me_
,
"AE failure; couldn't append entry"
);
r
->
success
=
0
;
return
-
1
;
}
static
int
__should_grant_vote
(
raft_server_private_t
*
me
,
msg_requestvote_t
*
vr
)
...
...
tests/test_server.c
View file @
e4c4029e
...
...
@@ -801,6 +801,44 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(
CuAssertTrue(tc, 2 == raft_get_log_count(r));
}
void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_log(
CuTest * tc)
{
void *r = raft_new();
raft_add_node(r, (void*)1, 1);
raft_add_node(r, (void*)2, 0);
raft_set_current_term(r, 1);
msg_appendentries_t ae;
msg_appendentries_response_t aer;
memset(&ae, 0, sizeof(msg_appendentries_t));
ae.term = 1;
ae.prev_log_idx = 0;
ae.prev_log_term = 1;
/* include 1 entry */
msg_entry_t e[2];
memset(&e, 0, sizeof(msg_entry_t) * 2);
e[0].id = 1;
ae.entries = e;
ae.n_entries = 1;
memset(&aer, 0, sizeof(aer));
raft_recv_appendentries(r, 1, &ae, &aer);
memset(&aer, 0, sizeof(aer));
raft_recv_appendentries(r, 1, &ae, &aer);
/* still successful even when no raft_append_entry() happened! */
CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 1, raft_get_log_count(r));
/* lets get the server to append 2 now! */
e[1].id = 2;
ae.n_entries = 2;
memset(&aer, 0, sizeof(aer));
raft_recv_appendentries(r, 1, &ae, &aer);
CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 2, raft_get_log_count(r));
}
/* If leaderCommit > commitidx, set commitidx =
* min(leaderCommit, last log idx) */
void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(
...
...
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