Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
RedisLabs Raft
Commits
59770f6c
Unverified
Commit
59770f6c
authored
Aug 11, 2021
by
Ozan Tezcan
Committed by
GitHub
Aug 11, 2021
Browse files
Fix: read operations will count acks correctly (#34)
parent
04cdff03
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/raft_server.c
View file @
59770f6c
...
...
@@ -1582,34 +1582,41 @@ void raft_entry_release_list(raft_entry_t **ety_list, size_t len)
static
int
msgid_cmp
(
const
void
*
a
,
const
void
*
b
)
{
return
*
(
raft_msg_id_t
*
)
a
-
*
(
raft_msg_id_t
*
)
b
;
raft_msg_id_t
va
=
*
((
raft_msg_id_t
*
)
a
);
raft_msg_id_t
vb
=
*
((
raft_msg_id_t
*
)
b
);
return
va
>
vb
?
-
1
:
1
;
}
raft_msg_id_t
quorum_msg_id
(
raft_server_t
*
me_
)
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
;
raft_msg_id_t
msg_ids
[
me
->
num_nodes
];
int
msg_ids_count
=
0
;
int
num_voters
=
0
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
for
(
int
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
raft_node_t
*
node
=
me
->
nodes
[
i
];
if
(
!
raft_node_is_voting
(
node
))
continue
;
if
(
me
->
node
==
node
)
{
msg_ids
[
msg_ids_count
++
]
=
me
->
msg_id
;
msg_ids
[
num_voters
++
]
=
me
->
msg_id
;
}
else
{
msg_ids
[
msg_ids_count
++
]
=
raft_node_get_last_acked_msgid
(
node
);
msg_ids
[
num_voters
++
]
=
raft_node_get_last_acked_msgid
(
node
);
}
}
qsort
(
msg_ids
,
msg_ids_count
,
sizeof
(
raft_msg_id_t
),
msgid_cmp
);
int
num_voting_nodes
=
raft_get_num_voting_nodes
(
me_
);
assert
(
num_voting_nodes
==
msg_ids_count
);
return
msg_ids
[
num_voting_nodes
-
(
num_voting_nodes
/
2
+
num_voting_nodes
%
2
)];
assert
(
num_voters
==
raft_get_num_voting_nodes
(
me_
));
/**
* Sort the acknowledged msg_ids in the descending order and return
* the median value. Median value means it's the highest msg_id
* acknowledged by the majority.
*/
qsort
(
msg_ids
,
num_voters
,
sizeof
(
raft_msg_id_t
),
msgid_cmp
);
return
msg_ids
[
num_voters
/
2
];
}
void
raft_queue_read_request
(
raft_server_t
*
me_
,
func_read_request_callback_f
cb
,
void
*
cb_arg
)
...
...
src/raft_server_properties.c
View file @
59770f6c
...
...
@@ -60,7 +60,7 @@ int raft_get_num_voting_nodes(raft_server_t* me_)
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
,
num
=
0
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
if
(
raft_node_is_active
(
me
->
nodes
[
i
])
&&
raft_node_is_voting
(
me
->
nodes
[
i
]))
if
(
raft_node_is_voting
(
me
->
nodes
[
i
]))
num
++
;
return
num
;
}
...
...
tests/test_server.c
View file @
59770f6c
...
...
@@ -3838,6 +3838,60 @@ void TestRaft_single_node_commits_noop(CuTest * tc)
CuAssertStrEquals
(
tc
,
"success"
,
str
);
}
void
quorum_msg_id_correctness_cb
(
void
*
arg
,
int
can_read
)
{
(
void
)
can_read
;
(
*
(
int
*
)
arg
)
++
;
}
void
TestRaft_quorum_msg_id_correctness
(
CuTest
*
tc
)
{
int
val
=
0
;
void
*
r
=
raft_new
();
raft_add_node
(
r
,
NULL
,
1
,
1
);
raft_add_node
(
r
,
NULL
,
2
,
0
);
raft_set_current_term
(
r
,
1
);
raft_become_leader
(
r
);
__RAFT_APPEND_ENTRY
(
r
,
1
,
1
,
"aaa"
);
raft_set_commit_idx
(
r
,
1
);
raft_periodic
(
r
,
1000
);
raft_queue_read_request
(
r
,
quorum_msg_id_correctness_cb
,
&
val
);
raft_periodic
(
r
,
2000
);
// Read request is pending as it requires two acks
CuAssertIntEquals
(
tc
,
0
,
val
);
// Second node acknowledges reaq req
raft_node_set_last_ack
(
raft_get_node
(
r
,
2
),
1
,
1
);
raft_periodic
(
r
,
2000
);
CuAssertIntEquals
(
tc
,
1
,
val
);
val
=
0
;
raft_add_node
(
r
,
NULL
,
3
,
0
);
raft_add_node
(
r
,
NULL
,
4
,
0
);
raft_periodic
(
r
,
1000
);
raft_queue_read_request
(
r
,
quorum_msg_id_correctness_cb
,
&
val
);
raft_periodic
(
r
,
2000
);
// Read request is pending as it requires three acks
CuAssertIntEquals
(
tc
,
0
,
val
);
// Second node acknowledges reaq req,
raft_node_set_last_ack
(
raft_get_node
(
r
,
2
),
2
,
1
);
raft_periodic
(
r
,
2000
);
CuAssertIntEquals
(
tc
,
0
,
val
);
// Third node acknowledges reaq req
raft_node_set_last_ack
(
raft_get_node
(
r
,
3
),
2
,
1
);
raft_periodic
(
r
,
2000
);
CuAssertIntEquals
(
tc
,
1
,
val
);
}
int
main
(
void
)
{
CuString
*
output
=
CuStringNew
();
...
...
@@ -3962,6 +4016,7 @@ int main(void)
SUITE_ADD_TEST
(
suite
,
TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_voting_committed
);
SUITE_ADD_TEST
(
suite
,
TestRaft_read_action_callback
);
SUITE_ADD_TEST
(
suite
,
TestRaft_single_node_commits_noop
);
SUITE_ADD_TEST
(
suite
,
TestRaft_quorum_msg_id_correctness
);
CuSuiteRun
(
suite
);
CuSuiteDetails
(
suite
,
output
);
...
...
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