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
d8799dd9
Unverified
Commit
d8799dd9
authored
Aug 31, 2021
by
Ozan Tezcan
Committed by
GitHub
Aug 31, 2021
Browse files
Fix : send snapshot when node's next index is snapshot's last included index (#47)
parent
2896eb00
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/raft_server.c
View file @
d8799dd9
...
...
@@ -1219,41 +1219,41 @@ raft_entry_t** raft_get_entries_from_idx(raft_server_t* me_, raft_index_t idx, i
int
raft_send_appendentries
(
raft_server_t
*
me_
,
raft_node_t
*
node
)
{
if
(
!
raft_node_is_active
(
node
))
{
return
0
;
}
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
assert
(
node
);
assert
(
node
!=
me
->
node
);
if
(
!
(
me
->
cb
.
send_appendentries
))
return
-
1
;
msg_appendentries_t
ae
=
{};
ae
.
term
=
me
->
current_term
;
ae
.
leader_commit
=
raft_get_commit_idx
(
me_
);
ae
.
prev_log_idx
=
0
;
ae
.
prev_log_term
=
0
;
ae
.
msg_id
=
me
->
msg_id
;
if
(
!
raft_node_is_active
(
node
))
{
return
0
;
}
raft_index_t
next_idx
=
raft_node_get_next_idx
(
node
);
/* figure out if the client needs a snapshot sent */
if
(
0
<
me
->
snapshot_last_idx
&&
next_idx
<
me
->
snapshot_last_idx
)
if
(
me
->
snapshot_last_idx
>
0
&&
next_idx
<
=
me
->
snapshot_last_idx
)
{
if
(
me
->
cb
.
send_snapshot
)
me
->
cb
.
send_snapshot
(
me_
,
me
->
udata
,
node
);
return
RAFT_ERR_NEEDS_SNAPSHOT
;
}
if
(
!
me
->
cb
.
send_appendentries
)
return
-
1
;
msg_appendentries_t
ae
=
{
.
term
=
me
->
current_term
,
.
leader_commit
=
raft_get_commit_idx
(
me_
),
.
msg_id
=
me
->
msg_id
,
};
ae
.
entries
=
raft_get_entries_from_idx
(
me_
,
next_idx
,
&
ae
.
n_entries
);
assert
((
!
ae
.
entries
&&
0
==
ae
.
n_entries
)
||
(
ae
.
entries
&&
0
<
ae
.
n_entries
));
/* previous log is the log just before the new logs */
if
(
1
<
next_idx
)
if
(
next_idx
>
1
)
{
raft_entry_t
*
prev_ety
=
raft_get_entry_from_idx
(
me_
,
next_idx
-
1
);
if
(
!
prev_ety
)
...
...
@@ -1498,7 +1498,7 @@ int raft_end_snapshot(raft_server_t *me_)
/* If needed, remove compacted logs */
int
e
=
me
->
log_impl
->
poll
(
me
->
log
,
me
->
snapshot_last_idx
+
1
);
if
(
e
!=
0
)
return
-
1
;
return
e
;
me
->
snapshot_in_progress
=
0
;
...
...
@@ -1511,8 +1511,7 @@ int raft_end_snapshot(raft_server_t *me_)
if
(
!
raft_is_leader
(
me_
))
return
0
;
int
i
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
for
(
int
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
raft_node_t
*
node
=
me
->
nodes
[
i
];
...
...
@@ -1522,7 +1521,7 @@ int raft_end_snapshot(raft_server_t *me_)
raft_index_t
next_idx
=
raft_node_get_next_idx
(
node
);
/* figure out if the client needs a snapshot sent */
if
(
0
<
me
->
snapshot_last_idx
&&
next_idx
<
me
->
snapshot_last_idx
)
if
(
me
->
snapshot_last_idx
>
0
&&
next_idx
<
=
me
->
snapshot_last_idx
)
{
if
(
me
->
cb
.
send_snapshot
)
me
->
cb
.
send_snapshot
(
me_
,
me
->
udata
,
node
);
...
...
tests/test_snapshotting.c
View file @
d8799dd9
...
...
@@ -63,8 +63,7 @@ static int __raft_send_appendentries_capture(raft_server_t* raft,
raft_node_t
*
node
,
msg_appendentries_t
*
msg
)
{
msg_appendentries_t
*
msg_captured
=
(
msg_appendentries_t
*
)
udata
;
memcpy
(
msg_captured
,
msg
,
sizeof
(
msg_appendentries_t
));
*
((
msg_appendentries_t
*
)
udata
)
=
*
msg
;
return
0
;
}
...
...
@@ -486,20 +485,20 @@ void TestRaft_follower_load_from_snapshot_fails_if_log_is_newer(CuTest * tc)
CuAssertIntEquals
(
tc
,
-
1
,
raft_begin_load_snapshot
(
r
,
2
,
2
));
}
void
TestRaft_leader_sends_
appendentries
_when_node_next_index_was_compacted
(
CuTest
*
tc
)
void
TestRaft_leader_sends_
snapshot
_when_node_next_index_was_compacted
(
CuTest
*
tc
)
{
raft_cbs_t
funcs
=
{
.
send_
appendentries
=
__raft_send_
appendentries_capture
,
.
send_
snapshot
=
__raft_send_
snapshot_increment
};
msg_appendentries_t
ae
;
int
increment
=
0
;
void
*
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
&
ae
);
raft_set_callbacks
(
r
,
&
funcs
,
&
increment
);
raft_node_t
*
node
;
raft_add_node
(
r
,
NULL
,
1
,
1
);
node
=
raft_add_node
(
r
,
NULL
,
2
,
0
);
raft_add_node
(
r
,
NULL
,
2
,
0
);
raft_add_node
(
r
,
NULL
,
3
,
0
);
/* entry 1 */
...
...
@@ -520,6 +519,23 @@ void TestRaft_leader_sends_appendentries_when_node_next_index_was_compacted(CuTe
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_current_term
(
r
,
2
);
/* verify snapshot is sent */
int
rc
=
raft_send_appendentries
(
r
,
node
);
CuAssertIntEquals
(
tc
,
RAFT_ERR_NEEDS_SNAPSHOT
,
rc
);
CuAssertIntEquals
(
tc
,
1
,
increment
);
/* update callbacks, verify correct appendreq is sent after the snapshot */
funcs
=
(
raft_cbs_t
)
{
.
send_appendentries
=
__raft_send_appendentries_capture
,
};
msg_appendentries_t
ae
;
raft_set_callbacks
(
r
,
&
funcs
,
&
ae
);
/* node wants an entry just one after the snapshot index */
raft_node_set_next_idx
(
node
,
raft_get_current_idx
(
r
)
+
1
);
CuAssertIntEquals
(
tc
,
0
,
raft_send_appendentries
(
r
,
node
));
CuAssertIntEquals
(
tc
,
2
,
ae
.
term
);
CuAssertIntEquals
(
tc
,
3
,
ae
.
prev_log_idx
);
...
...
@@ -652,7 +668,7 @@ void TestRaft_leader_sends_appendentries_with_correct_prev_log_idx_when_snapshot
*/
raft_node_t
*
p
=
raft_add_node
(
r
,
NULL
,
2
,
0
);
CuAssertTrue
(
tc
,
NULL
!=
p
);
raft_node_set_next_idx
(
p
,
4
);
raft_node_set_next_idx
(
p
,
5
);
/* receive appendentries messages */
raft_send_appendentries
(
r
,
p
);
...
...
@@ -783,7 +799,7 @@ int main(void)
SUITE_ADD_TEST
(
suite
,
TestRaft_follower_load_from_snapshot_fails_if_already_loaded
);
SUITE_ADD_TEST
(
suite
,
TestRaft_follower_load_from_snapshot_does_not_break_cluster_safety
);
SUITE_ADD_TEST
(
suite
,
TestRaft_follower_load_from_snapshot_fails_if_log_is_newer
);
SUITE_ADD_TEST
(
suite
,
TestRaft_leader_sends_
appendentries
_when_node_next_index_was_compacted
);
SUITE_ADD_TEST
(
suite
,
TestRaft_leader_sends_
snapshot
_when_node_next_index_was_compacted
);
SUITE_ADD_TEST
(
suite
,
TestRaft_recv_entry_fails_if_snapshot_in_progress
);
SUITE_ADD_TEST
(
suite
,
TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set
);
SUITE_ADD_TEST
(
suite
,
TestRaft_follower_recv_appendentries_is_successful_when_previous_log_idx_equals_snapshot_last_idx
);
...
...
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