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
Willemt Raft
Commits
e95a1a87
Commit
e95a1a87
authored
Jan 13, 2014
by
willem
Browse files
Split out public and private function defs
parent
81c6277e
Changes
9
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
e95a1a87
...
...
@@ -24,7 +24,7 @@ $(TEST_DIR)/main_test.c:
fi
cd
$(TEST_DIR)
&&
sh make-tests.sh
"test_*.c"
>
main_test.c
&&
cd
..
tests_main
:
raft_server.c raft_log.c raft_node.c $(TEST_DIR)/main_test.c $(TEST_DIR)/test_server.c
$(TEST_DIR)/test_server_request_vote.c
$(TEST_DIR)/test_node.c $(TEST_DIR)/test_log.c $(TEST_DIR)/test_scenario.c $(TEST_DIR)/mock_send_functions.c $(TEST_DIR)/CuTest.c $(LLQUEUE_DIR)/linked_list_queue.c
tests_main
:
raft_server.c raft_log.c raft_node.c $(TEST_DIR)/main_test.c $(TEST_DIR)/test_server.c $(TEST_DIR)/test_node.c $(TEST_DIR)/test_log.c $(TEST_DIR)/test_scenario.c $(TEST_DIR)/mock_send_functions.c $(TEST_DIR)/CuTest.c $(LLQUEUE_DIR)/linked_list_queue.c
$(CC)
$(CCFLAGS)
-o
$@
$^
./tests_main
...
...
raft.h
View file @
e95a1a87
/**
* Copyright (c) 2013, Willem-Hendrik Thiart
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* @file
* @author Willem Thiart himself@willemthiart.com
* @version 0.1
*/
enum
{
RAFT_STATE_NONE
,
...
...
@@ -136,79 +145,89 @@ typedef void* raft_server_t;
typedef
void
*
raft_node_t
;
/**
* Initialise a new raft server */
* Initialise a new raft server
* Election timeout defaults to 1000 milliseconds */
raft_server_t
*
raft_new
();
/**
* De-Initialise raft server */
void
raft_free
(
raft_server_t
*
me_
);
void
raft_set_callbacks
(
raft_server_t
*
me
,
raft_cbs_t
*
funcs
,
void
*
caller
);
void
raft_election_start
(
raft_server_t
*
me
);
void
raft_
become_leader
(
raft_server_t
*
me
);
/**
* Set callbacks
* @param funcs Callbacks
* @param cb_ctx The context that we include with all callbacks */
void
raft_
set_callbacks
(
raft_server_t
*
me
,
raft_cbs_t
*
funcs
,
void
*
cb_ctx
);
void
raft_become_candidate
(
raft_server_t
*
me
);
/**
* Set configuration
* @param nodes Array of nodes, end of array is marked by NULL entry
* @param me_idx Which node is myself */
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_node_configuration_t
*
nodes
,
int
me_idx
);
int
raft_receive_append_entries
(
raft_server_t
*
me
,
msg_appendentries_t
*
ae
);
/**
* Set election timeout */
void
raft_set_election_timeout
(
raft_server_t
*
me
,
int
millisec
);
/**
*
@return 0 on error
*/
int
raft_
periodic
(
raft_server_t
*
me
,
int
m
sec_since_last_period
);
*
Set request timeout
*/
void
raft_
set_request_timeout
(
raft_server_t
*
me
_
,
int
m
illisec
);
/**
* Run actions that are dependent on time passing
* @return 0 on error */
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
int
node
,
msg_appendentries_response_t
*
aer
);
int
raft_periodic
(
raft_server_t
*
me
,
int
msec_since_last_period
);
/**
* Receive an appendentries message
* @param node Who sent us the response
* @param ae The appendentries message
* @return 0 on error */
int
raft_recv_appendentries
(
raft_server_t
*
me
,
int
node
,
msg_appendentries_t
*
ae
);
/**
* Receive a response from an appendentries message we sent
* @param node Who sent us the response
* @param r The appendentries response
* @return 0 on error */
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
int
node
,
msg_appendentries_response_t
*
r
);
/**
* Receive a requestvote message
* @param node Who sent us the message
* @param vr The requestvote message
* @return 0 on error */
int
raft_recv_requestvote
(
raft_server_t
*
me
,
int
node
,
msg_requestvote_t
*
vr
);
/**
* Receive a response from a requestvote message we sent
* @param node Who sent us the response
* @param r The requestvote response
* @param node The node this response was sent by */
int
raft_recv_requestvote_response
(
raft_server_t
*
me
,
int
node
,
msg_requestvote_response_t
*
r
);
void
raft_execute_entry
(
raft_server_t
*
me
);
void
raft_set_election_timeout
(
raft_server_t
*
me
,
int
millisec
);
/**
* Receive an ENTRY message.
* Append entry to log
* Send APPENDENTRIES to followers */
int
raft_recv_entry
(
raft_server_t
*
me
,
int
node
,
msg_entry_t
*
cmd
);
int
raft_get_election_timeout
(
raft_server_t
*
me
);
void
raft_vote
(
raft_server_t
*
me
,
int
node
);
raft_node_t
*
raft_add_node
(
raft_server_t
*
me
,
int
node_udata
);
int
raft_remove_node
(
raft_server_t
*
me
,
int
node
);
/**
* @return number of nodes that this server has */
int
raft_get_num_nodes
(
raft_server_t
*
me
);
/**
* Receive an ENTRY message.
* Append entry to log
* Send APPENDENTRIES to followers */
int
raft_recv_entry
(
raft_server_t
*
me
,
int
node
,
msg_entry_t
*
cmd
);
/**
* @return number of items within log */
int
raft_get_log_count
(
raft_server_t
*
me
);
void
raft_set_current_term
(
raft_server_t
*
me
,
int
term
);
void
raft_set_current_idx
(
raft_server_t
*
me
,
int
idx
);
int
raft_get_current_term
(
raft_server_t
*
me
);
void
raft_set_current_idx
(
raft_server_t
*
me
,
int
idx
);
int
raft_get_current_idx
(
raft_server_t
*
me
);
int
raft_is_follower
(
raft_server_t
*
me
);
...
...
@@ -217,54 +236,14 @@ int raft_is_leader(raft_server_t* me);
int
raft_is_candidate
(
raft_server_t
*
me
);
/**
* @return 0 on error */
int
raft_send_requestvote
(
raft_server_t
*
me
,
int
node
);
void
raft_send_appendentries
(
raft_server_t
*
me
,
int
node
);
void
raft_send_appendentries_all
(
raft_server_t
*
me_
);
/**
* Appends entry using the current term.
* Note: we make the assumption that current term is up-to-date
* @return 0 if unsuccessful */
int
raft_append_entry
(
raft_server_t
*
me_
,
raft_entry_t
*
c
);
int
raft_get_timeout_elapsed
(
raft_server_t
*
me
);
void
raft_set_commit_idx
(
raft_server_t
*
me
,
int
commit_idx
);
void
raft_set_last_applied_idx
(
raft_server_t
*
me
,
int
idx
);
void
raft_set_state
(
raft_server_t
*
me_
,
int
state
);
void
raft_set_request_timeout
(
raft_server_t
*
me_
,
int
millisec
);
int
raft_get_last_applied_idx
(
raft_server_t
*
me
);
raft_node_t
*
raft_node_new
(
void
*
udata
);
int
raft_node_is_leader
(
raft_node_t
*
node
);
int
raft_node_get_next_idx
(
raft_node_t
*
node
);
void
raft_node_set_next_idx
(
raft_node_t
*
node
,
int
nextIdx
);
/**
* Set configuration
* @param nodes Array of nodes, end of array is marked by NULL entry
* @param me_idx Which node is myself */
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_node_configuration_t
*
nodes
,
int
me_idx
);
int
raft_votes_is_majority
(
const
int
nnodes
,
const
int
nvotes
);
/**
* Apply entry at lastApplied + 1. Entry becomes 'committed'.
* @return 1 if entry committed, 0 otherwise */
int
raft_apply_entry
(
raft_server_t
*
me_
);
raft_entry_t
*
raft_get_entry_from_idx
(
raft_server_t
*
me_
,
int
idx
);
raft_node_t
*
raft_get_node
(
raft_server_t
*
me_
,
int
nodeid
);
...
...
raft_private.h
0 → 100644
View file @
e95a1a87
/**
* Copyright (c) 2013, Willem-Hendrik Thiart
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* @file
* @author Willem Thiart himself@willemthiart.com
* @version 0.1
*/
/* These are here for testing purposes */
void
raft_election_start
(
raft_server_t
*
me
);
void
raft_become_leader
(
raft_server_t
*
me
);
void
raft_become_candidate
(
raft_server_t
*
me
);
void
raft_vote
(
raft_server_t
*
me
,
int
node
);
void
raft_set_current_term
(
raft_server_t
*
me
,
int
term
);
void
raft_set_current_idx
(
raft_server_t
*
me
,
int
idx
);
/**
* @return 0 on error */
int
raft_send_requestvote
(
raft_server_t
*
me
,
int
node
);
void
raft_send_appendentries
(
raft_server_t
*
me
,
int
node
);
void
raft_send_appendentries_all
(
raft_server_t
*
me_
);
/**
* Apply entry at lastApplied + 1. Entry becomes 'committed'.
* @return 1 if entry committed, 0 otherwise */
int
raft_apply_entry
(
raft_server_t
*
me_
);
/**
* Appends entry using the current term.
* Note: we make the assumption that current term is up-to-date
* @return 0 if unsuccessful */
int
raft_append_entry
(
raft_server_t
*
me_
,
raft_entry_t
*
c
);
void
raft_set_commit_idx
(
raft_server_t
*
me
,
int
commit_idx
);
void
raft_set_last_applied_idx
(
raft_server_t
*
me
,
int
idx
);
void
raft_set_state
(
raft_server_t
*
me_
,
int
state
);
raft_node_t
*
raft_node_new
(
void
*
udata
);
void
raft_node_set_next_idx
(
raft_node_t
*
node
,
int
nextIdx
);
int
raft_votes_is_majority
(
const
int
nnodes
,
const
int
nvotes
);
raft_server.c
View file @
e95a1a87
...
...
@@ -19,6 +19,7 @@
#include <stdarg.h>
#include "raft.h"
#include "raft_private.h"
#include "raft_log.h"
typedef
struct
{
...
...
@@ -91,6 +92,7 @@ typedef struct {
raft_cbs_t
cb
;
void
*
cb_ctx
;
/* my node ID */
int
nodeid
;
union
{
...
...
@@ -116,7 +118,7 @@ raft_server_t* raft_new()
{
raft_server_private_t
*
me
;
if
(
!
(
me
=
calloc
(
1
,
sizeof
(
raft_server_private_t
))))
if
(
!
(
me
=
calloc
(
1
,
sizeof
(
raft_server_private_t
))))
return
NULL
;
me
->
current_term
=
1
;
...
...
@@ -124,7 +126,7 @@ raft_server_t* raft_new()
me
->
current_idx
=
1
;
me
->
timeout_elapsed
=
0
;
me
->
log
=
log_new
();
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
me
->
request_timeout
=
200
;
me
->
election_timeout
=
1000
;
return
(
void
*
)
me
;
...
...
@@ -153,7 +155,6 @@ void raft_election_start(raft_server_t* me_)
__log
(
me_
,
NULL
,
"election starting: %d %d, term: %d"
,
me
->
election_timeout
,
me
->
timeout_elapsed
,
me
->
current_term
);
/* time to throw our hat in */
raft_become_candidate
(
me_
);
}
...
...
@@ -247,7 +248,7 @@ raft_entry_t* raft_get_entry_from_idx(raft_server_t* me_, int etyidx)
}
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
int
node
,
msg_appendentries_response_t
*
ae
r
)
int
node
,
msg_appendentries_response_t
*
r
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_node_t
*
p
;
...
...
@@ -256,11 +257,11 @@ int raft_recv_appendentries_response(raft_server_t* me_,
p
=
raft_get_node
(
me_
,
node
);
if
(
1
==
ae
r
->
success
)
if
(
1
==
r
->
success
)
{
int
i
;
for
(
i
=
ae
r
->
first_idx
;
i
<=
ae
r
->
current_idx
;
i
++
)
for
(
i
=
r
->
first_idx
;
i
<=
r
->
current_idx
;
i
++
)
log_mark_node_has_committed
(
me
->
log
,
i
);
while
(
1
)
...
...
@@ -589,7 +590,7 @@ void raft_send_appendentries(raft_server_t* me_, int node)
raft_node_t
*
p
=
raft_get_node
(
me_
,
node
);
ae
.
term
=
me
->
current_term
;
ae
.
leader_id
=
raft_get_my_id
(
me_
)
;
ae
.
leader_id
=
me
->
nodeid
;
ae
.
prev_log_term
=
raft_node_get_next_idx
(
p
);
// TODO:
ae
.
prev_log_idx
=
0
;
...
...
@@ -640,7 +641,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
votes
+=
1
;
}
if
(
raft_get_voted_for
(
me_
)
==
raft_get_my_id
(
me_
)
)
if
(
me
->
voted_for
==
me
->
nodeid
)
votes
+=
1
;
return
votes
;
...
...
@@ -684,17 +685,6 @@ int raft_get_num_nodes(raft_server_t* me_)
return
((
raft_server_private_t
*
)
me_
)
->
nnodes
;
}
void
raft_set_state
(
raft_server_t
*
me_
,
int
state
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
state
=
state
;
}
int
raft_get_state
(
raft_server_t
*
me_
)
{
return
((
raft_server_private_t
*
)
me_
)
->
state
;
}
raft_node_t
*
raft_get_node
(
raft_server_t
*
me_
,
int
nodeid
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
...
...
@@ -784,4 +774,15 @@ int raft_get_commit_idx(raft_server_t* me_)
return
((
raft_server_private_t
*
)
me_
)
->
commit_idx
;
}
void
raft_set_state
(
raft_server_t
*
me_
,
int
state
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
state
=
state
;
}
int
raft_get_state
(
raft_server_t
*
me_
)
{
return
((
raft_server_private_t
*
)
me_
)
->
state
;
}
/*--------------------------------------------------------------79-characters-*/
tests/test_log.c
View file @
e95a1a87
...
...
@@ -8,6 +8,7 @@
#include "CuTest.h"
#include "raft.h"
#include "raft_private.h"
#include "raft_log.h"
void
TestLog_new_is_empty
(
CuTest
*
tc
)
...
...
tests/test_node.c
View file @
e95a1a87
...
...
@@ -8,6 +8,7 @@
#include "CuTest.h"
#include "raft.h"
#include "raft_private.h"
void
TestRaft_node_set_nextIdx
(
CuTest
*
tc
)
{
...
...
tests/test_scenario.c
View file @
e95a1a87
...
...
@@ -8,6 +8,7 @@
#include "CuTest.h"
#include "raft.h"
#include "raft_private.h"
#include "mock_send_functions.h"
void
TestRaft_scenario_leader_appears
(
CuTest
*
tc
)
...
...
tests/test_server.c
View file @
e95a1a87
...
...
@@ -8,6 +8,7 @@
#include "CuTest.h"
#include "raft.h"
#include "raft_private.h"
#include "mock_send_functions.h"
// TODO: leader doesn't timeout and cause election
...
...
tests/test_server_request_vote.c
deleted
100644 → 0
View file @
81c6277e
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "CuTest.h"
#include "raft.h"
#include "mock_send_functions.h"
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