From: Cyrill Gorcunov <gorcunov@gmail.com> To: tml <tarantool-patches@dev.tarantool.org> Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Subject: [Tarantool-patches] [RFC 3/4] cfg: prepare symbolic evaluation of replication_synchro_quorum Date: Thu, 19 Nov 2020 22:40:59 +0300 [thread overview] Message-ID: <20201119194100.840495-4-gorcunov@gmail.com> (raw) In-Reply-To: <20201119194100.840495-1-gorcunov@gmail.com> Prepare scaffolds to evaluate replication_synchro_quorum, since we don't yet update the undeneath engines we accept and verify the formulas but refuse to proceed. In next patch we will support dynamic evaluation of the quorum number. Part-of #5446 Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> --- src/box/box.cc | 82 +++++++++++++++++++++++++++++++++++++++- src/box/box.h | 1 + src/box/lua/load_cfg.lua | 3 +- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/box/box.cc b/src/box/box.cc index 5fcf28cb3..5f7ddfa99 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -562,10 +562,90 @@ box_check_replication_sync_lag(void) return lag; } +/** + * Evaluate replicaion syncro quorum number from a formula. + */ +int +eval_replication_synchro_quorum(int nr_replicas) +{ + const char fmt[] = + "local f, err = loadstring(\"return (%s)\")\n" + "if not f then return 'failed to load \"%s\"' end\n" + "setfenv(f, { n = %d })\n" + "local ok, res = pcall(f)\n" + "if not ok then return res end\n" + "return math.floor(res)\n"; + char buf[512]; + int value = -1; + + errno = 0; + + const char *expr = cfg_gets("replication_synchro_quorum"); + size_t ret = snprintf(buf, sizeof(buf), fmt, expr, + expr, nr_replicas); + if (ret >= sizeof(buf)) { + errno = EINVAL; + diag_set(ClientError, ER_CFG, + "replication_synchro_quorum", + "the expression is too big"); + return -1; + } + + luaL_loadstring(tarantool_L, buf); + lua_call(tarantool_L, 0, 1); + + if (lua_isnumber(tarantool_L, -1)) { + value = (int)lua_tonumber(tarantool_L, -1); + } else { + assert(lua_isstring(tarantool_L, -1)); + errno = EINVAL; + diag_set(ClientError, ER_CFG, + "replication_synchro_quorum", + lua_tostring(tarantool_L, -1)); + } + lua_pop(tarantool_L, 1); + return value; +} + static int box_check_replication_synchro_quorum(void) { - int quorum = cfg_geti("replication_synchro_quorum"); + int quorum = 0; + + if (!cfg_isnumber("replication_synchro_quorum")) { + /* + * When validating a formula it must return a + * positive value for a single node and maximum + * possible replicas because the quorum will be + * evaluated on each new replica registration, + * starting from a single node. + */ + int v[] = {1, VCLOCK_MAX-1}; + for (size_t i = 0; i < lengthof(v); i++) { + quorum = eval_replication_synchro_quorum(v[i]); + if (quorum < 0 && errno == EINVAL) + return -1; + } + + /* + * Once syntax is valid we should pass the real + * default value from replication module itself + * to evaluate the actual value to use. + */ + int value = replication_synchro_quorum; + quorum = eval_replication_synchro_quorum(value); + /* + * FIXME: Until we get full support. + */ + diag_set(ClientError, ER_CFG, + "replication_synchro_quorum", + "symbolic evaluation is not yet supported"); + diag_log(); + quorum = -1; + } else { + quorum = cfg_geti("replication_synchro_quorum"); + } + if (quorum <= 0 || quorum >= VCLOCK_MAX) { diag_set(ClientError, ER_CFG, "replication_synchro_quorum", "the value must be greater than zero and less than " diff --git a/src/box/box.h b/src/box/box.h index b47a220b7..8f438faab 100644 --- a/src/box/box.h +++ b/src/box/box.h @@ -252,6 +252,7 @@ void box_set_replication_connect_timeout(void); void box_set_replication_connect_quorum(void); void box_set_replication_sync_lag(void); int box_set_replication_synchro_quorum(void); +int eval_replication_synchro_quorum(int nr_replicas); int box_set_replication_synchro_timeout(void); void box_set_replication_sync_timeout(void); void box_set_replication_skip_conflict(void); diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua index 76e2e92c2..26725e08d 100644 --- a/src/box/lua/load_cfg.lua +++ b/src/box/lua/load_cfg.lua @@ -172,7 +172,7 @@ local template_cfg = { replication_timeout = 'number', replication_sync_lag = 'number', replication_sync_timeout = 'number', - replication_synchro_quorum = 'number', + replication_synchro_quorum = 'string, number', replication_synchro_timeout = 'number', replication_connect_timeout = 'number', replication_connect_quorum = 'number', @@ -368,7 +368,6 @@ local dynamic_cfg_skip_at_load = { replication_connect_quorum = true, replication_sync_lag = true, replication_sync_timeout = true, - replication_synchro_quorum = true, replication_synchro_timeout = true, replication_skip_conflict = true, replication_anon = true, -- 2.26.2
next prev parent reply other threads:[~2020-11-19 19:41 UTC|newest] Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-11-19 19:40 [Tarantool-patches] [RFC 0/4] qsync: evaluate replication_synchro_quorum dynamically Cyrill Gorcunov 2020-11-19 19:40 ` [Tarantool-patches] [RFC 1/4] cfg: add cfg_isnumber helper Cyrill Gorcunov 2020-11-20 9:53 ` Serge Petrenko 2020-11-19 19:40 ` [Tarantool-patches] [RFC 2/4] qsync: move synchro quorum update to separate routine Cyrill Gorcunov 2020-11-20 10:06 ` Serge Petrenko 2020-11-20 11:01 ` Cyrill Gorcunov 2020-11-20 11:39 ` Serge Petrenko 2020-11-20 11:47 ` Cyrill Gorcunov 2020-11-19 19:40 ` Cyrill Gorcunov [this message] 2020-11-20 10:32 ` [Tarantool-patches] [RFC 3/4] cfg: prepare symbolic evaluation of replication_synchro_quorum Serge Petrenko 2020-11-20 11:34 ` Cyrill Gorcunov 2020-11-20 11:56 ` Serge Petrenko 2020-11-20 12:14 ` Cyrill Gorcunov 2020-11-26 14:38 ` Mons Anderson 2020-11-26 14:44 ` Cyrill Gorcunov 2020-11-26 16:01 ` Mons Anderson 2020-11-19 19:41 ` [Tarantool-patches] [RFC 4/4] qsync: allow to specify replication_synchro_quorum as a formula Cyrill Gorcunov 2020-11-20 10:50 ` Serge Petrenko 2020-11-20 12:01 ` Cyrill Gorcunov 2020-11-20 12:41 ` Serge Petrenko 2020-11-20 15:00 ` Cyrill Gorcunov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20201119194100.840495-4-gorcunov@gmail.com \ --to=gorcunov@gmail.com \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [RFC 3/4] cfg: prepare symbolic evaluation of replication_synchro_quorum' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox