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
Hide 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