From 5a16660af11c84dd1ae442c46f1f7c0351b5f6a0 Mon Sep 17 00:00:00 2001 From: Steve Dee Date: Fri, 17 Jan 2014 12:13:46 -0800 Subject: [PATCH] Skeleton for raft --- include/v/vere.h | 13 +++++++ v/loop.c | 1 + v/raft.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/include/v/vere.h b/include/v/vere.h index fca1cfb3ac..de2c000961 100644 --- a/include/v/vere.h +++ b/include/v/vere.h @@ -382,6 +382,13 @@ struct _u2_utty* nex_u; // next in host list } u2_utty; + /* u2_raft: raft state. + */ + typedef struct { + uv_tcp_t wax_u; + uv_timer_t tim_u; + } u2_raft; + /* u2_rnam: raft peer name. */ typedef struct _u2_rnam { @@ -436,6 +443,7 @@ u2_cttp* ctp_u; // http connections u2_utty* uty_u; // all terminals u2_utty* tem_u; // main terminal (1) + u2_raft raf_u; // raft event log u2_ulog lug_u; // event log u2_ames sam_u; // packet interface u2_save sav_u; // autosave @@ -998,3 +1006,8 @@ */ u2_bean u2_raft_readopt(u2_ropt* rop_u, const c3_c* arg_c); + + /* u2_raft_io_init(): initialize raft I/O. + */ + void + u2_raft_io_init(void); diff --git a/v/loop.c b/v/loop.c index d6e19b4d0d..317131b751 100644 --- a/v/loop.c +++ b/v/loop.c @@ -161,6 +161,7 @@ u2_loop_signal_memory() static void _lo_init() { + u2_raft_io_init(); u2_unix_io_init(); u2_ames_io_init(); u2_term_io_init(); diff --git a/v/raft.c b/v/raft.c index ec06fb7b86..1ac74c3276 100644 --- a/v/raft.c +++ b/v/raft.c @@ -11,9 +11,18 @@ #include "all.h" #include "v/vere.h" + +/* _raft_election_rand(): pseudorandom component of election timeout. +*/ +static c3_w +_raft_election_rand() +{ + return ((float) rand() / RAND_MAX) * 150; +} + /* _raft_readname(): parse a raft host:port peer name. */ -u2_bean +static u2_bean _raft_readname(u2_ropt* rop_u, const c3_c* str_c, c3_w siz_w) { u2_rnam* nam_u = malloc(sizeof(*nam_u)); @@ -62,3 +71,80 @@ u2_raft_readopt(u2_ropt* rop_u, const c3_c* arg_c) } return _raft_readname(rop_u, arg_c, strlen(arg_c)); } + +static void +_raft_listen_cb(uv_stream_t* wax_u, c3_i sas_i) +{ +} + +static void +_raft_time_cb(uv_timer_t* tim_u, c3_i sas_i) +{ + u2_raft* raf_u = tim_u->data; + //uL(fprintf(uH, "raft: time\n")); +} + +/* _raft_foll_init(): begin, follower mode. +*/ +static void +_raft_foll_init(u2_raft* raf_u) +{ + uL(fprintf(uH, "raft: starting follower\n")); + + if ( 0 != uv_tcp_init(u2L, &raf_u->wax_u) ) { + uL(fprintf(uH, "raft: init: %s\n", uv_strerror(uv_last_error(u2L)))); + c3_assert(0); + } + + // Bind the listener. + { + struct sockaddr_in add_u; + + memset(&add_u, 0, sizeof(add_u)); + add_u.sin_family = AF_INET; + add_u.sin_addr.s_addr = htonl(INADDR_ANY); + add_u.sin_port = htons(u2_Host.ops_u.rop_u.por_s); + + if ( 0 != uv_tcp_bind(&raf_u->wax_u, add_u) ) { + uL(fprintf(uH, "raft: bind: %s\n", uv_strerror(uv_last_error(u2L)))); + c3_assert(0); + } + else { + if ( 0 != uv_listen((uv_stream_t*)&raf_u->wax_u, 16, _raft_listen_cb) ) { + uL(fprintf(uH, "raft: listen: %s\n", uv_strerror(uv_last_error(u2L)))); + c3_assert(0); + } + else { + uL(fprintf(uH, "raft: on TCP %d\n", u2_Host.ops_u.rop_u.por_s)); + } + } + } + + // Start the initial election timeout. + { + uv_timer_init(u2L, &raf_u->tim_u); + raf_u->tim_u.data = raf_u; + uv_timer_start(&raf_u->tim_u, _raft_time_cb, _raft_election_rand(), 0); + } +} + +/* _raft_lone_init(): begin, single-instance mode. +*/ +static void +_raft_lone_init(u2_raft* raf_u) +{ + uL(fprintf(uH, "raft: single-instance mode\n")); +} + +void +u2_raft_io_init() +{ + u2_raft* raf_u = &u2_Host.raf_u; + + if ( 0 == u2_Host.ops_u.rop_u.por_s ) { + _raft_lone_init(raf_u); + } + else { + _raft_foll_init(raf_u); + } +}