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
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)
...
@@ -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
)
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_msg_id_t
quorum_msg_id
(
raft_server_t
*
me_
)
{
{
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
;
raft_msg_id_t
msg_ids
[
me
->
num_nodes
];
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
];
raft_node_t
*
node
=
me
->
nodes
[
i
];
if
(
!
raft_node_is_voting
(
node
))
if
(
!
raft_node_is_voting
(
node
))
continue
;
continue
;
if
(
me
->
node
==
node
)
{
if
(
me
->
node
==
node
)
{
msg_ids
[
msg_ids_count
++
]
=
me
->
msg_id
;
msg_ids
[
num_voters
++
]
=
me
->
msg_id
;
}
else
{
}
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
);
assert
(
num_voters
==
raft_get_num_voting_nodes
(
me_
));
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
)];
* 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
)
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_)
...
@@ -60,7 +60,7 @@ int raft_get_num_voting_nodes(raft_server_t* me_)
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
raft_server_private_t
*
me
=
(
raft_server_private_t
*
)
me_
;
int
i
,
num
=
0
;
int
i
,
num
=
0
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
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
++
;
num
++
;
return
num
;
return
num
;
}
}
...
...
tests/test_server.c
View file @
59770f6c
...
@@ -3838,6 +3838,60 @@ void TestRaft_single_node_commits_noop(CuTest * tc)
...
@@ -3838,6 +3838,60 @@ void TestRaft_single_node_commits_noop(CuTest * tc)
CuAssertStrEquals
(
tc
,
"success"
,
str
);
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
)
int
main
(
void
)
{
{
CuString
*
output
=
CuStringNew
();
CuString
*
output
=
CuStringNew
();
...
@@ -3962,6 +4016,7 @@ int main(void)
...
@@ -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_leader_recv_appendentries_response_set_has_sufficient_logs_after_voting_committed
);
SUITE_ADD_TEST
(
suite
,
TestRaft_read_action_callback
);
SUITE_ADD_TEST
(
suite
,
TestRaft_read_action_callback
);
SUITE_ADD_TEST
(
suite
,
TestRaft_single_node_commits_noop
);
SUITE_ADD_TEST
(
suite
,
TestRaft_single_node_commits_noop
);
SUITE_ADD_TEST
(
suite
,
TestRaft_quorum_msg_id_correctness
);
CuSuiteRun
(
suite
);
CuSuiteRun
(
suite
);
CuSuiteDetails
(
suite
,
output
);
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