From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp34.i.mail.ru (smtp34.i.mail.ru [94.100.177.94]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 7DD24469719 for ; Tue, 29 Sep 2020 17:36:07 +0300 (MSK) References: From: Serge Petrenko Message-ID: <605398aa-8fc6-2cd7-52f4-ccad3161bc5e@tarantool.org> Date: Tue, 29 Sep 2020 17:36:06 +0300 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8"; format="flowed" Content-Transfer-Encoding: 8bit Content-Language: en-GB Subject: Re: [Tarantool-patches] [PATCH 1/1] [tosquash] raft: don't expose 'raft' name to public List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Vladislav Shpilevoy , tarantool-patches@dev.tarantool.org 29.09.2020 00:05, Vladislav Shpilevoy пишет: > Raft is a name of the algorithm of leader election and and sync > replication. Its exposure to public has 2 issues: not everyone > know what is raft, and such users won't understand the new > box.cfg options as well as box.info.raft purpose; the options and > info will outdate in case we every switch to anything from Raft. > > This patch makes it called 'leadership'. So from the options > name and box.info section name it is clear what this is about. > And less problems with potential switching to something after > Raft. Hi! Thanks for the patch! As  discussed, let's replace `leadership_` with `election_`. So that it'll be `election_is_enabled` `election_is_candidate` `election_timeout` `box.info.election` > --- > Branch: http://github.com/tarantool/tarantool/tree/gh-1146-raft > Issue: https://github.com/tarantool/tarantool/issues/1146 > > src/box/box.cc | 59 ++++----- > src/box/box.h | 6 +- > src/box/lua/cfg.cc | 18 +-- > src/box/lua/info.c | 4 +- > src/box/lua/load_cfg.lua | 30 ++--- > ...t_basic.result => leadership_basic.result} | 117 ++++++++--------- > test/replication/leadership_basic.test.lua | 117 +++++++++++++++++ > ...aft_replica.lua => leadership_replica.lua} | 8 +- > test/replication/leadership_replica1.lua | 1 + > test/replication/leadership_replica2.lua | 1 + > test/replication/leadership_replica3.lua | 1 + > test/replication/raft_basic.test.lua | 118 ------------------ > test/replication/raft_replica1.lua | 1 - > test/replication/raft_replica2.lua | 1 - > test/replication/raft_replica3.lua | 1 - > 15 files changed, 242 insertions(+), 241 deletions(-) > rename test/replication/{raft_basic.result => leadership_basic.result} (52%) > create mode 100644 test/replication/leadership_basic.test.lua > rename test/replication/{raft_replica.lua => leadership_replica.lua} (80%) > create mode 120000 test/replication/leadership_replica1.lua > create mode 120000 test/replication/leadership_replica2.lua > create mode 120000 test/replication/leadership_replica3.lua > delete mode 100644 test/replication/raft_basic.test.lua > delete mode 120000 test/replication/raft_replica1.lua > delete mode 120000 test/replication/raft_replica2.lua > delete mode 120000 test/replication/raft_replica3.lua > > diff --git a/src/box/box.cc b/src/box/box.cc > index 957bf4d7a..2ca238c76 100644 > --- a/src/box/box.cc > +++ b/src/box/box.cc > @@ -478,33 +478,33 @@ box_check_uri(const char *source, const char *option_name) > } > > static int > -box_check_raft_is_enabled(void) > +box_check_leadership_is_enabled(void) > { > - int b = cfg_getb("raft_is_enabled"); > + int b = cfg_getb("leadership_is_enabled"); > if (b < 0) { > - diag_set(ClientError, ER_CFG, "raft_is_enabled", > + diag_set(ClientError, ER_CFG, "leadership_is_enabled", > "the value must be a boolean"); > } > return b; > } > > static int > -box_check_raft_is_candidate(void) > +box_check_leadership_is_candidate(void) > { > - int b = cfg_getb("raft_is_candidate"); > + int b = cfg_getb("leadership_is_candidate"); > if (b < 0) { > - diag_set(ClientError, ER_CFG, "raft_is_candidate", > + diag_set(ClientError, ER_CFG, "leadership_is_candidate", > "the value must be a boolean"); > } > return b; > } > > static double > -box_check_raft_election_timeout(void) > +box_check_leadership_election_timeout(void) > { > - double d = cfg_getd("raft_election_timeout"); > + double d = cfg_getd("leadership_election_timeout"); > if (d <= 0) { > - diag_set(ClientError, ER_CFG, "raft_election_timeout", > + diag_set(ClientError, ER_CFG, "leadership_election_timeout", > "the value must be a positive number"); > return -1; > } > @@ -768,11 +768,11 @@ box_check_config(void) > box_check_uri(cfg_gets("listen"), "listen"); > box_check_instance_uuid(&uuid); > box_check_replicaset_uuid(&uuid); > - if (box_check_raft_is_enabled() < 0) > + if (box_check_leadership_is_enabled() < 0) > diag_raise(); > - if (box_check_raft_is_candidate() < 0) > + if (box_check_leadership_is_candidate() < 0) > diag_raise(); > - if (box_check_raft_election_timeout() < 0) > + if (box_check_leadership_election_timeout() < 0) > diag_raise(); > box_check_replication(); > box_check_replication_timeout(); > @@ -797,9 +797,9 @@ box_check_config(void) > } > > int > -box_set_raft_is_enabled(void) > +box_set_leadership_is_enabled(void) > { > - int b = box_check_raft_is_enabled(); > + int b = box_check_leadership_is_enabled(); > if (b < 0) > return -1; > raft_cfg_is_enabled(b); > @@ -807,9 +807,9 @@ box_set_raft_is_enabled(void) > } > > int > -box_set_raft_is_candidate(void) > +box_set_leadership_is_candidate(void) > { > - int b = box_check_raft_is_candidate(); > + int b = box_check_leadership_is_candidate(); > if (b < 0) > return -1; > raft_cfg_is_candidate(b); > @@ -817,9 +817,9 @@ box_set_raft_is_candidate(void) > } > > int > -box_set_raft_election_timeout(void) > +box_set_leadership_election_timeout(void) > { > - double d = box_check_raft_election_timeout(); > + double d = box_check_leadership_election_timeout(); > if (d < 0) > return -1; > raft_cfg_election_timeout(d); > @@ -2777,23 +2777,24 @@ box_cfg_xc(void) > fiber_gc(); > is_box_configured = true; > /* > - * Fill in Raft parameters after bootstrap. Before it is not possible - > - * there may be Raft data to recover from WAL and snapshot. Also until > - * recovery is done, it is not possible to write new records into WAL. > - * It is also totally safe, because relaying is not started until the > - * box is configured. So it can't happen, that this Raft node will try > - * to relay to another Raft node without Raft enabled leading to > + * Fill in leadership parameters after bootstrap. Before it is not > + * possible - there may be relevant data to recover from WAL and > + * snapshot. Also until recovery is done, it is not possible to write > + * new records into WAL. It is also totally safe, because relaying is > + * not started until the box is configured. So it can't happen, that > + * this leadership-enabled node will try to relay to another > + * leadership-enabled node without leadership enabled leading to > * disconnect. > */ > - if (box_set_raft_is_candidate() != 0) > + if (box_set_leadership_is_candidate() != 0) > diag_raise(); > - if (box_set_raft_election_timeout() != 0) > + if (box_set_leadership_election_timeout() != 0) > diag_raise(); > /* > - * Raft is enabled last. So as all the parameters are installed by that > - * time. > + * Leadership is enabled last. So as all the parameters are installed by > + * that time. > */ > - if (box_set_raft_is_enabled() != 0) > + if (box_set_leadership_is_enabled() != 0) > diag_raise(); > > title("running"); > diff --git a/src/box/box.h b/src/box/box.h > index 637d10dd3..e55c30627 100644 > --- a/src/box/box.h > +++ b/src/box/box.h > @@ -245,9 +245,9 @@ void box_set_vinyl_memory(void); > void box_set_vinyl_max_tuple_size(void); > void box_set_vinyl_cache(void); > void box_set_vinyl_timeout(void); > -int box_set_raft_is_enabled(void); > -int box_set_raft_is_candidate(void); > -int box_set_raft_election_timeout(void); > +int box_set_leadership_is_enabled(void); > +int box_set_leadership_is_candidate(void); > +int box_set_leadership_election_timeout(void); > void box_set_replication_timeout(void); > void box_set_replication_connect_timeout(void); > void box_set_replication_connect_quorum(void); > diff --git a/src/box/lua/cfg.cc b/src/box/lua/cfg.cc > index 339b85f9d..44f7ec727 100644 > --- a/src/box/lua/cfg.cc > +++ b/src/box/lua/cfg.cc > @@ -270,25 +270,25 @@ lbox_cfg_set_worker_pool_threads(struct lua_State *L) > } > > static int > -lbox_cfg_set_raft_is_enabled(struct lua_State *L) > +lbox_cfg_set_leadership_is_enabled(struct lua_State *L) > { > - if (box_set_raft_is_enabled() != 0) > + if (box_set_leadership_is_enabled() != 0) > luaT_error(L); > return 0; > } > > static int > -lbox_cfg_set_raft_is_candidate(struct lua_State *L) > +lbox_cfg_set_leadership_is_candidate(struct lua_State *L) > { > - if (box_set_raft_is_candidate() != 0) > + if (box_set_leadership_is_candidate() != 0) > luaT_error(L); > return 0; > } > > static int > -lbox_cfg_set_raft_election_timeout(struct lua_State *L) > +lbox_cfg_set_leadership_election_timeout(struct lua_State *L) > { > - if (box_set_raft_election_timeout() != 0) > + if (box_set_leadership_election_timeout() != 0) > luaT_error(L); > return 0; > } > @@ -406,9 +406,9 @@ box_lua_cfg_init(struct lua_State *L) > {"cfg_set_vinyl_max_tuple_size", lbox_cfg_set_vinyl_max_tuple_size}, > {"cfg_set_vinyl_cache", lbox_cfg_set_vinyl_cache}, > {"cfg_set_vinyl_timeout", lbox_cfg_set_vinyl_timeout}, > - {"cfg_set_raft_is_enabled", lbox_cfg_set_raft_is_enabled}, > - {"cfg_set_raft_is_candidate", lbox_cfg_set_raft_is_candidate}, > - {"cfg_set_raft_election_timeout", lbox_cfg_set_raft_election_timeout}, > + {"cfg_set_leadership_is_enabled", lbox_cfg_set_leadership_is_enabled}, > + {"cfg_set_leadership_is_candidate", lbox_cfg_set_leadership_is_candidate}, > + {"cfg_set_leadership_election_timeout", lbox_cfg_set_leadership_election_timeout}, > {"cfg_set_replication_timeout", lbox_cfg_set_replication_timeout}, > {"cfg_set_replication_connect_quorum", lbox_cfg_set_replication_connect_quorum}, > {"cfg_set_replication_connect_timeout", lbox_cfg_set_replication_connect_timeout}, > diff --git a/src/box/lua/info.c b/src/box/lua/info.c > index 8e1dbd497..d1d552d20 100644 > --- a/src/box/lua/info.c > +++ b/src/box/lua/info.c > @@ -579,7 +579,7 @@ lbox_info_listen(struct lua_State *L) > } > > static int > -lbox_info_raft(struct lua_State *L) > +lbox_info_leadership(struct lua_State *L) > { > lua_createtable(L, 0, 4); > lua_pushstring(L, raft_state_strs[raft.state]); > @@ -611,7 +611,7 @@ static const struct luaL_Reg lbox_info_dynamic_meta[] = { > {"vinyl", lbox_info_vinyl}, > {"sql", lbox_info_sql}, > {"listen", lbox_info_listen}, > - {"raft", lbox_info_raft}, > + {"leadership", lbox_info_leadership}, > {NULL, NULL} > }; > > diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua > index 2c98fd837..d2d58356c 100644 > --- a/src/box/lua/load_cfg.lua > +++ b/src/box/lua/load_cfg.lua > @@ -86,9 +86,9 @@ local default_cfg = { > checkpoint_wal_threshold = 1e18, > checkpoint_count = 2, > worker_pool_threads = 4, > - raft_is_enabled = false, > - raft_is_candidate = true, > - raft_election_timeout = 5, > + leadership_is_enabled = false, > + leadership_is_candidate = true, > + leadership_election_timeout = 5, > replication_timeout = 1, > replication_sync_lag = 10, > replication_sync_timeout = 300, > @@ -166,9 +166,9 @@ local template_cfg = { > read_only = 'boolean', > hot_standby = 'boolean', > worker_pool_threads = 'number', > - raft_is_enabled = 'boolean', > - raft_is_candidate = 'boolean', > - raft_election_timeout = 'number', > + leadership_is_enabled = 'boolean', > + leadership_is_candidate = 'boolean', > + leadership_election_timeout = 'number', > replication_timeout = 'number', > replication_sync_lag = 'number', > replication_sync_timeout = 'number', > @@ -285,9 +285,9 @@ local dynamic_cfg = { > require('title').update(box.cfg.custom_proc_title) > end, > force_recovery = function() end, > - raft_is_enabled = private.cfg_set_raft_is_enabled, > - raft_is_candidate = private.cfg_set_raft_is_candidate, > - raft_election_timeout = private.cfg_set_raft_election_timeout, > + leadership_is_enabled = private.cfg_set_leadership_is_enabled, > + leadership_is_candidate = private.cfg_set_leadership_is_candidate, > + leadership_election_timeout = private.cfg_set_leadership_election_timeout, > replication_timeout = private.cfg_set_replication_timeout, > replication_connect_timeout = private.cfg_set_replication_connect_timeout, > replication_connect_quorum = private.cfg_set_replication_connect_quorum, > @@ -342,9 +342,9 @@ local dynamic_cfg_order = { > -- the new one. This should be fixed when box.cfg is able to > -- apply some parameters together and atomically. > replication_anon = 250, > - raft_is_enabled = 300, > - raft_is_candidate = 310, > - raft_election_timeout = 320, > + leadership_is_enabled = 300, > + leadership_is_candidate = 310, > + leadership_election_timeout = 320, > } > > local function sort_cfg_cb(l, r) > @@ -362,9 +362,9 @@ local dynamic_cfg_skip_at_load = { > vinyl_cache = true, > vinyl_timeout = true, > too_long_threshold = true, > - raft_is_enabled = true, > - raft_is_candidate = true, > - raft_election_timeout = true, > + leadership_is_enabled = true, > + leadership_is_candidate = true, > + leadership_election_timeout = true, > replication = true, > replication_timeout = true, > replication_connect_timeout = true, > diff --git a/test/replication/raft_basic.result b/test/replication/leadership_basic.result > similarity index 52% > rename from test/replication/raft_basic.result > rename to test/replication/leadership_basic.result > index 3421227fb..51dc468e0 100644 > --- a/test/replication/raft_basic.result > +++ b/test/replication/leadership_basic.result > @@ -6,54 +6,56 @@ test_run = require('test_run').new() > -- gh-1146: Raft protocol for automated leader election. > -- > > -old_raft_election_timeout = box.cfg.raft_election_timeout > +old_leadership_election_timeout = box.cfg.leadership_election_timeout > | --- > | ... > > --- Raft is turned off by default. > -assert(not box.cfg.raft_is_enabled) > +-- Leadership is turned off by default. > +assert(not box.cfg.leadership_is_enabled) > | --- > | - true > | ... > --- Is candidate by default. Although it does not matter, until Raft is > +-- Is candidate by default. Although it does not matter, until leadership is > -- turned on. > -assert(box.cfg.raft_is_candidate) > +assert(box.cfg.leadership_is_candidate) > | --- > | - true > | ... > --- Ensure raft options are validated. > -box.cfg{raft_is_enabled = 100} > +-- Ensure leadership options are validated. > +box.cfg{leadership_is_enabled = 100} > | --- > - | - error: 'Incorrect value for option ''raft_is_enabled'': should be of type boolean' > + | - error: 'Incorrect value for option ''leadership_is_enabled'': should be of type > + | boolean' > | ... > -box.cfg{raft_is_candidate = 100} > +box.cfg{leadership_is_candidate = 100} > | --- > - | - error: 'Incorrect value for option ''raft_is_candidate'': should be of type boolean' > + | - error: 'Incorrect value for option ''leadership_is_candidate'': should be of type > + | boolean' > | ... > -box.cfg{raft_election_timeout = -1} > +box.cfg{leadership_election_timeout = -1} > | --- > - | - error: 'Incorrect value for option ''raft_election_timeout'': the value must be > - | a positive number' > + | - error: 'Incorrect value for option ''leadership_election_timeout'': the value must > + | be a positive number' > | ... > -box.cfg{raft_election_timeout = 0} > +box.cfg{leadership_election_timeout = 0} > | --- > - | - error: 'Incorrect value for option ''raft_election_timeout'': the value must be > - | a positive number' > + | - error: 'Incorrect value for option ''leadership_election_timeout'': the value must > + | be a positive number' > | ... > > --- When Raft is disabled, the instance is a follower. Does not > --- try to become a leader, and does not block write operations. > -term = box.info.raft.term > +-- When leadership is disabled, the instance is a follower. Does not try to > +-- become a leader, and does not block write operations. > +term = box.info.leadership.term > | --- > | ... > -vote = box.info.raft.vote > +vote = box.info.leadership.vote > | --- > | ... > -assert(box.info.raft.state == 'follower') > +assert(box.info.leadership.state == 'follower') > | --- > | - true > | ... > -assert(box.info.raft.leader == 0) > +assert(box.info.leadership.leader == 0) > | --- > | - true > | ... > @@ -62,15 +64,14 @@ assert(not box.info.ro) > | - true > | ... > > --- Turned on Raft blocks writes until the instance becomes a > --- leader. > -box.cfg{raft_is_candidate = false} > +-- Turned on leadership blocks writes until the instance becomes a leader. > +box.cfg{leadership_is_candidate = false} > | --- > | ... > -box.cfg{raft_is_enabled = true} > +box.cfg{leadership_is_enabled = true} > | --- > | ... > -assert(box.info.raft.state == 'follower') > +assert(box.info.leadership.state == 'follower') > | --- > | - true > | ... > @@ -80,55 +81,55 @@ assert(box.info.ro) > | ... > -- Term is not changed, because the instance can't be a candidate, > -- and therefore didn't try to vote nor to bump the term. > -assert(box.info.raft.term == term) > +assert(box.info.leadership.term == term) > | --- > | - true > | ... > -assert(box.info.raft.vote == vote) > +assert(box.info.leadership.vote == vote) > | --- > | - true > | ... > -assert(box.info.raft.leader == 0) > +assert(box.info.leadership.leader == 0) > | --- > | - true > | ... > > -- Candidate instance votes immediately, if sees no leader. > -box.cfg{raft_election_timeout = 1000} > +box.cfg{leadership_election_timeout = 1000} > | --- > | ... > -box.cfg{raft_is_candidate = true} > +box.cfg{leadership_is_candidate = true} > | --- > | ... > -test_run:wait_cond(function() return box.info.raft.state == 'leader' end) > +test_run:wait_cond(function() return box.info.leadership.state == 'leader' end) > | --- > | - true > | ... > -assert(box.info.raft.term > term) > +assert(box.info.leadership.term > term) > | --- > | - true > | ... > -assert(box.info.raft.vote == box.info.id) > +assert(box.info.leadership.vote == box.info.id) > | --- > | - true > | ... > -assert(box.info.raft.leader == box.info.id) > +assert(box.info.leadership.leader == box.info.id) > | --- > | - true > | ... > > box.cfg{ \ > - raft_is_enabled = false, \ > - raft_is_candidate = true, \ > - raft_election_timeout = old_raft_election_timeout \ > + leadership_is_enabled = false, \ > + leadership_is_candidate = true, \ > + leadership_election_timeout = old_leadership_election_timeout \ > } > | --- > | ... > > -- > --- See if bootstrap with Raft enabled works. > +-- See if bootstrap with leadership enabled works. > -- > -SERVERS = {'raft_replica1', 'raft_replica2', 'raft_replica3'} > +SERVERS = {'leadership_replica1', 'leadership_replica2', 'leadership_replica3'} > | --- > | ... > test_run:create_cluster(SERVERS, "replication") > @@ -137,19 +138,19 @@ test_run:create_cluster(SERVERS, "replication") > test_run:wait_fullmesh(SERVERS) > | --- > | ... > -is_leader_cmd = 'return box.info.raft.state == \'leader\'' > +is_leader_cmd = 'return box.info.leadership.state == \'leader\'' > | --- > | ... > -leader_id_cmd = 'return box.info.raft.leader' > +leader_id_cmd = 'return box.info.leadership.leader' > | --- > | ... > -is_r1_leader = test_run:eval('raft_replica1', is_leader_cmd)[1] > +is_r1_leader = test_run:eval('leadership_replica1', is_leader_cmd)[1] > | --- > | ... > -is_r2_leader = test_run:eval('raft_replica2', is_leader_cmd)[1] > +is_r2_leader = test_run:eval('leadership_replica2', is_leader_cmd)[1] > | --- > | ... > -is_r3_leader = test_run:eval('raft_replica3', is_leader_cmd)[1] > +is_r3_leader = test_run:eval('leadership_replica3', is_leader_cmd)[1] > | --- > | ... > leader_count = is_r1_leader and 1 or 0 > @@ -166,13 +167,13 @@ assert(leader_count == 1) > | - true > | ... > -- All nodes have the same leader. > -r1_leader = test_run:eval('raft_replica1', leader_id_cmd)[1] > +r1_leader = test_run:eval('leadership_replica1', leader_id_cmd)[1] > | --- > | ... > -r2_leader = test_run:eval('raft_replica2', leader_id_cmd)[1] > +r2_leader = test_run:eval('leadership_replica2', leader_id_cmd)[1] > | --- > | ... > -r3_leader = test_run:eval('raft_replica3', leader_id_cmd)[1] > +r3_leader = test_run:eval('leadership_replica3', leader_id_cmd)[1] > | --- > | ... > assert(r1_leader ~= 0) > @@ -201,17 +202,17 @@ nonleader2_name = nil > | --- > | ... > if is_r1_leader then \ > - leader_name = 'raft_replica1' \ > - nonleader1_name = 'raft_replica2' \ > - nonleader2_name = 'raft_replica3' \ > + leader_name = 'leadership_replica1' \ > + nonleader1_name = 'leadership_replica2' \ > + nonleader2_name = 'leadership_replica3' \ > elseif is_r2_leader then \ > - leader_name = 'raft_replica2' \ > - nonleader1_name = 'raft_replica1' \ > - nonleader2_name = 'raft_replica3' \ > + leader_name = 'leadership_replica2' \ > + nonleader1_name = 'leadership_replica1' \ > + nonleader2_name = 'leadership_replica3' \ > else \ > - leader_name = 'raft_replica3' \ > - nonleader1_name = 'raft_replica1' \ > - nonleader2_name = 'raft_replica2' \ > + leader_name = 'leadership_replica3' \ > + nonleader1_name = 'leadership_replica1' \ > + nonleader2_name = 'leadership_replica2' \ > end > | --- > | ... > diff --git a/test/replication/leadership_basic.test.lua b/test/replication/leadership_basic.test.lua > new file mode 100644 > index 000000000..f60459206 > --- /dev/null > +++ b/test/replication/leadership_basic.test.lua > @@ -0,0 +1,117 @@ > +test_run = require('test_run').new() > +-- > +-- gh-1146: Raft protocol for automated leader election. > +-- > + > +old_leadership_election_timeout = box.cfg.leadership_election_timeout > + > +-- Leadership is turned off by default. > +assert(not box.cfg.leadership_is_enabled) > +-- Is candidate by default. Although it does not matter, until leadership is > +-- turned on. > +assert(box.cfg.leadership_is_candidate) > +-- Ensure leadership options are validated. > +box.cfg{leadership_is_enabled = 100} > +box.cfg{leadership_is_candidate = 100} > +box.cfg{leadership_election_timeout = -1} > +box.cfg{leadership_election_timeout = 0} > + > +-- When leadership is disabled, the instance is a follower. Does not try to > +-- become a leader, and does not block write operations. > +term = box.info.leadership.term > +vote = box.info.leadership.vote > +assert(box.info.leadership.state == 'follower') > +assert(box.info.leadership.leader == 0) > +assert(not box.info.ro) > + > +-- Turned on leadership blocks writes until the instance becomes a leader. > +box.cfg{leadership_is_candidate = false} > +box.cfg{leadership_is_enabled = true} > +assert(box.info.leadership.state == 'follower') > +assert(box.info.ro) > +-- Term is not changed, because the instance can't be a candidate, > +-- and therefore didn't try to vote nor to bump the term. > +assert(box.info.leadership.term == term) > +assert(box.info.leadership.vote == vote) > +assert(box.info.leadership.leader == 0) > + > +-- Candidate instance votes immediately, if sees no leader. > +box.cfg{leadership_election_timeout = 1000} > +box.cfg{leadership_is_candidate = true} > +test_run:wait_cond(function() return box.info.leadership.state == 'leader' end) > +assert(box.info.leadership.term > term) > +assert(box.info.leadership.vote == box.info.id) > +assert(box.info.leadership.leader == box.info.id) > + > +box.cfg{ \ > + leadership_is_enabled = false, \ > + leadership_is_candidate = true, \ > + leadership_election_timeout = old_leadership_election_timeout \ > +} > + > +-- > +-- See if bootstrap with leadership enabled works. > +-- > +SERVERS = {'leadership_replica1', 'leadership_replica2', 'leadership_replica3'} > +test_run:create_cluster(SERVERS, "replication") > +test_run:wait_fullmesh(SERVERS) > +is_leader_cmd = 'return box.info.leadership.state == \'leader\'' > +leader_id_cmd = 'return box.info.leadership.leader' > +is_r1_leader = test_run:eval('leadership_replica1', is_leader_cmd)[1] > +is_r2_leader = test_run:eval('leadership_replica2', is_leader_cmd)[1] > +is_r3_leader = test_run:eval('leadership_replica3', is_leader_cmd)[1] > +leader_count = is_r1_leader and 1 or 0 > +leader_count = leader_count + (is_r2_leader and 1 or 0) > +leader_count = leader_count + (is_r3_leader and 1 or 0) > +assert(leader_count == 1) > +-- All nodes have the same leader. > +r1_leader = test_run:eval('leadership_replica1', leader_id_cmd)[1] > +r2_leader = test_run:eval('leadership_replica2', leader_id_cmd)[1] > +r3_leader = test_run:eval('leadership_replica3', leader_id_cmd)[1] > +assert(r1_leader ~= 0) > +assert(r1_leader == r2_leader) > +assert(r1_leader == r3_leader) > + > +-- > +-- Leader death starts a new election. > +-- > +leader_name = nil > +nonleader1_name = nil > +nonleader2_name = nil > +if is_r1_leader then \ > + leader_name = 'leadership_replica1' \ > + nonleader1_name = 'leadership_replica2' \ > + nonleader2_name = 'leadership_replica3' \ > +elseif is_r2_leader then \ > + leader_name = 'leadership_replica2' \ > + nonleader1_name = 'leadership_replica1' \ > + nonleader2_name = 'leadership_replica3' \ > +else \ > + leader_name = 'leadership_replica3' \ > + nonleader1_name = 'leadership_replica1' \ > + nonleader2_name = 'leadership_replica2' \ > +end > +-- Lower the quorum so the 2 alive nodes could elect a new leader when the third > +-- node dies. > +test_run:switch(nonleader1_name) > +box.cfg{replication_synchro_quorum = 2} > +-- Switch via default where the names are defined. > +test_run:switch('default') > +test_run:switch(nonleader2_name) > +box.cfg{replication_synchro_quorum = 2} > + > +test_run:switch('default') > +test_run:cmd(string.format('stop server %s', leader_name)) > +test_run:wait_cond(function() \ > + is_r1_leader = test_run:eval(nonleader1_name, is_leader_cmd)[1] \ > + is_r2_leader = test_run:eval(nonleader2_name, is_leader_cmd)[1] \ > + return is_r1_leader or is_r2_leader \ > +end) > +r1_leader = test_run:eval(nonleader1_name, leader_id_cmd)[1] > +r2_leader = test_run:eval(nonleader2_name, leader_id_cmd)[1] > +assert(r1_leader ~= 0) > +assert(r1_leader == r2_leader) > + > +test_run:cmd(string.format('start server %s', leader_name)) > + > +test_run:drop_cluster(SERVERS) > diff --git a/test/replication/raft_replica.lua b/test/replication/leadership_replica.lua > similarity index 80% > rename from test/replication/raft_replica.lua > rename to test/replication/leadership_replica.lua > index 8b4c740d8..b1444ecec 100644 > --- a/test/replication/raft_replica.lua > +++ b/test/replication/leadership_replica.lua > @@ -17,11 +17,11 @@ box.cfg({ > instance_uri(3), > }, > replication_timeout = 0.1, > - raft_is_enabled = true, > - raft_is_candidate = true, > - raft_election_timeout = 0.1, > + leadership_is_enabled = true, > + leadership_is_candidate = true, > + leadership_election_timeout = 0.1, > replication_synchro_quorum = 3, > - -- To reveal more Raft logs. > + -- To reveal more leadership logs. > log_level = 6, > }) > > diff --git a/test/replication/leadership_replica1.lua b/test/replication/leadership_replica1.lua > new file mode 120000 > index 000000000..e81800b8c > --- /dev/null > +++ b/test/replication/leadership_replica1.lua > @@ -0,0 +1 @@ > +leadership_replica.lua > \ No newline at end of file > diff --git a/test/replication/leadership_replica2.lua b/test/replication/leadership_replica2.lua > new file mode 120000 > index 000000000..e81800b8c > --- /dev/null > +++ b/test/replication/leadership_replica2.lua > @@ -0,0 +1 @@ > +leadership_replica.lua > \ No newline at end of file > diff --git a/test/replication/leadership_replica3.lua b/test/replication/leadership_replica3.lua > new file mode 120000 > index 000000000..e81800b8c > --- /dev/null > +++ b/test/replication/leadership_replica3.lua > @@ -0,0 +1 @@ > +leadership_replica.lua > \ No newline at end of file > diff --git a/test/replication/raft_basic.test.lua b/test/replication/raft_basic.test.lua > deleted file mode 100644 > index b8e5a5eaf..000000000 > --- a/test/replication/raft_basic.test.lua > +++ /dev/null > @@ -1,118 +0,0 @@ > -test_run = require('test_run').new() > --- > --- gh-1146: Raft protocol for automated leader election. > --- > - > -old_raft_election_timeout = box.cfg.raft_election_timeout > - > --- Raft is turned off by default. > -assert(not box.cfg.raft_is_enabled) > --- Is candidate by default. Although it does not matter, until Raft is > --- turned on. > -assert(box.cfg.raft_is_candidate) > --- Ensure raft options are validated. > -box.cfg{raft_is_enabled = 100} > -box.cfg{raft_is_candidate = 100} > -box.cfg{raft_election_timeout = -1} > -box.cfg{raft_election_timeout = 0} > - > --- When Raft is disabled, the instance is a follower. Does not > --- try to become a leader, and does not block write operations. > -term = box.info.raft.term > -vote = box.info.raft.vote > -assert(box.info.raft.state == 'follower') > -assert(box.info.raft.leader == 0) > -assert(not box.info.ro) > - > --- Turned on Raft blocks writes until the instance becomes a > --- leader. > -box.cfg{raft_is_candidate = false} > -box.cfg{raft_is_enabled = true} > -assert(box.info.raft.state == 'follower') > -assert(box.info.ro) > --- Term is not changed, because the instance can't be a candidate, > --- and therefore didn't try to vote nor to bump the term. > -assert(box.info.raft.term == term) > -assert(box.info.raft.vote == vote) > -assert(box.info.raft.leader == 0) > - > --- Candidate instance votes immediately, if sees no leader. > -box.cfg{raft_election_timeout = 1000} > -box.cfg{raft_is_candidate = true} > -test_run:wait_cond(function() return box.info.raft.state == 'leader' end) > -assert(box.info.raft.term > term) > -assert(box.info.raft.vote == box.info.id) > -assert(box.info.raft.leader == box.info.id) > - > -box.cfg{ \ > - raft_is_enabled = false, \ > - raft_is_candidate = true, \ > - raft_election_timeout = old_raft_election_timeout \ > -} > - > --- > --- See if bootstrap with Raft enabled works. > --- > -SERVERS = {'raft_replica1', 'raft_replica2', 'raft_replica3'} > -test_run:create_cluster(SERVERS, "replication") > -test_run:wait_fullmesh(SERVERS) > -is_leader_cmd = 'return box.info.raft.state == \'leader\'' > -leader_id_cmd = 'return box.info.raft.leader' > -is_r1_leader = test_run:eval('raft_replica1', is_leader_cmd)[1] > -is_r2_leader = test_run:eval('raft_replica2', is_leader_cmd)[1] > -is_r3_leader = test_run:eval('raft_replica3', is_leader_cmd)[1] > -leader_count = is_r1_leader and 1 or 0 > -leader_count = leader_count + (is_r2_leader and 1 or 0) > -leader_count = leader_count + (is_r3_leader and 1 or 0) > -assert(leader_count == 1) > --- All nodes have the same leader. > -r1_leader = test_run:eval('raft_replica1', leader_id_cmd)[1] > -r2_leader = test_run:eval('raft_replica2', leader_id_cmd)[1] > -r3_leader = test_run:eval('raft_replica3', leader_id_cmd)[1] > -assert(r1_leader ~= 0) > -assert(r1_leader == r2_leader) > -assert(r1_leader == r3_leader) > - > --- > --- Leader death starts a new election. > --- > -leader_name = nil > -nonleader1_name = nil > -nonleader2_name = nil > -if is_r1_leader then \ > - leader_name = 'raft_replica1' \ > - nonleader1_name = 'raft_replica2' \ > - nonleader2_name = 'raft_replica3' \ > -elseif is_r2_leader then \ > - leader_name = 'raft_replica2' \ > - nonleader1_name = 'raft_replica1' \ > - nonleader2_name = 'raft_replica3' \ > -else \ > - leader_name = 'raft_replica3' \ > - nonleader1_name = 'raft_replica1' \ > - nonleader2_name = 'raft_replica2' \ > -end > --- Lower the quorum so the 2 alive nodes could elect a new leader when the third > --- node dies. > -test_run:switch(nonleader1_name) > -box.cfg{replication_synchro_quorum = 2} > --- Switch via default where the names are defined. > -test_run:switch('default') > -test_run:switch(nonleader2_name) > -box.cfg{replication_synchro_quorum = 2} > - > -test_run:switch('default') > -test_run:cmd(string.format('stop server %s', leader_name)) > -test_run:wait_cond(function() \ > - is_r1_leader = test_run:eval(nonleader1_name, is_leader_cmd)[1] \ > - is_r2_leader = test_run:eval(nonleader2_name, is_leader_cmd)[1] \ > - return is_r1_leader or is_r2_leader \ > -end) > -r1_leader = test_run:eval(nonleader1_name, leader_id_cmd)[1] > -r2_leader = test_run:eval(nonleader2_name, leader_id_cmd)[1] > -assert(r1_leader ~= 0) > -assert(r1_leader == r2_leader) > - > -test_run:cmd(string.format('start server %s', leader_name)) > - > -test_run:drop_cluster(SERVERS) > diff --git a/test/replication/raft_replica1.lua b/test/replication/raft_replica1.lua > deleted file mode 120000 > index d1f4d6f25..000000000 > --- a/test/replication/raft_replica1.lua > +++ /dev/null > @@ -1 +0,0 @@ > -raft_replica.lua > \ No newline at end of file > diff --git a/test/replication/raft_replica2.lua b/test/replication/raft_replica2.lua > deleted file mode 120000 > index d1f4d6f25..000000000 > --- a/test/replication/raft_replica2.lua > +++ /dev/null > @@ -1 +0,0 @@ > -raft_replica.lua > \ No newline at end of file > diff --git a/test/replication/raft_replica3.lua b/test/replication/raft_replica3.lua > deleted file mode 120000 > index d1f4d6f25..000000000 > --- a/test/replication/raft_replica3.lua > +++ /dev/null > @@ -1 +0,0 @@ > -raft_replica.lua > \ No newline at end of file -- Serge Petrenko