<HTML><BODY><div id="composeWebView_editable_content" data-mailruapp-compose-id="composeWebView_editable_content" style="text-align: left;"><div>Hi!</div><div><br></div><div>It resolves only these 2 keys order, AFAIU. How about introduce an ordered table in Tarantool, so that whole cfg and later introduced tables can preserve the order? An example of implementation <a href="http://lua-users.org/wiki/OrderedTable">http://lua-users.org/wiki/OrderedTable</a></div><div><br></div><div>Regards,</div><div>Sergos </div><div><br></div><div id="mail-app-auto-default-signature"><br><br>Sent from Mail.ru app for iOS<br></div><br><br>Saturday, 28 September 2019, 21:10 +0300 from Vladislav Shpilevoy <v.shpilevoy@tarantool.org>:<br><div id="composeWebView_previouse_content" data-mailruapp-compose-id="composeWebView_previouse_content"><blockquote id="mail-app-auto-quote" style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(11, 102, 249); margin: 10px 0px 10px 5px; padding: 0px 0px 0px 10px; border-top-color: rgb(25, 25, 25) !important; border-right-color: rgb(25, 25, 25) !important; border-bottom-color: rgb(25, 25, 25) !important; display: inherit;" data-darkosha-id="1:1"><div class="js-helper js-readmsg-msg" data-darkosha-id="1:2" style="border-color: rgb(25, 25, 25) !important;">
<style type="text/css" data-darkosha-id="1:3" style="border-color: rgb(25, 25, 25) !important;"></style>
<div data-darkosha-id="1:4" style="border-color: rgb(25, 25, 25) !important;">
<base target="_self" href="https://e.mail.ru/" data-darkosha-id="1:5" style="border-color: rgb(25, 25, 25) !important;">
<div id="style_15696942311933654905_BODY" data-darkosha-id="1:6" style="border-color: rgb(25, 25, 25) !important;">box.cfg, being called with a table with several options, may<br data-darkosha-id="1:7" style="border-color: rgb(25, 25, 25) !important;">
apply them in an arbitrary order because of how Lua stores<br data-darkosha-id="1:8" style="border-color: rgb(25, 25, 25) !important;">
tables.<br data-darkosha-id="1:9" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:10" style="border-color: rgb(25, 25, 25) !important;">
But sometimes the order matters. For example, when in one box.cfg<br data-darkosha-id="1:11" style="border-color: rgb(25, 25, 25) !important;">
both listen and replication are updated. If replication includes<br data-darkosha-id="1:12" style="border-color: rgb(25, 25, 25) !important;">
self, then it just won't work before listen.<br data-darkosha-id="1:13" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:14" style="border-color: rgb(25, 25, 25) !important;">
The patch makes listen be applied always before replication. This<br data-darkosha-id="1:15" style="border-color: rgb(25, 25, 25) !important;">
is done via introduction of a generic way to specify an order of<br data-darkosha-id="1:16" style="border-color: rgb(25, 25, 25) !important;">
all box.cfg options at reconfiguration.<br data-darkosha-id="1:17" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:18" style="border-color: rgb(25, 25, 25) !important;">
Closes #4433<br data-darkosha-id="1:19" style="border-color: rgb(25, 25, 25) !important;">
---<br data-darkosha-id="1:20" style="border-color: rgb(25, 25, 25) !important;">
Branch: <a href="https://github.com/tarantool/tarantool/tree/gerold103/gh-4433-replication-cfg-order" target="_blank" data-darkosha-id="1:21" style="color: rgb(203, 138, 255) !important;">https://github.com/tarantool/tarantool/tree/gerold103/gh-4433-replication-cfg-order</a><br data-darkosha-id="1:22" style="border-color: rgb(25, 25, 25) !important;">
Issue: <a href="https://github.com/tarantool/tarantool/issues/4433" target="_blank" data-darkosha-id="1:23" style="color: rgb(203, 138, 255) !important;">https://github.com/tarantool/tarantool/issues/4433</a><br data-darkosha-id="1:24" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:25" style="border-color: rgb(25, 25, 25) !important;">
Note, there is no a test. Appeared, that order of keys in a Lua<br data-darkosha-id="1:26" style="border-color: rgb(25, 25, 25) !important;">
table is too unstable. The same table is being iterated<br data-darkosha-id="1:27" style="border-color: rgb(25, 25, 25) !important;">
differently in an interactive console, and in a test file. In<br data-darkosha-id="1:28" style="border-color: rgb(25, 25, 25) !important;">
particular, these two cfgs:<br data-darkosha-id="1:29" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:30" style="border-color: rgb(25, 25, 25) !important;">
box.cfg{replication = {...}, listen = ...}<br data-darkosha-id="1:31" style="border-color: rgb(25, 25, 25) !important;">
box.cfg{listen = ..., replication = {...}}<br data-darkosha-id="1:32" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:33" style="border-color: rgb(25, 25, 25) !important;">
Both update listen before replication even before my patch, by a<br data-darkosha-id="1:34" style="border-color: rgb(25, 25, 25) !important;">
coincidence. But in an interactive console the first test hangs.<br data-darkosha-id="1:35" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:36" style="border-color: rgb(25, 25, 25) !important;">
src/box/lua/load_cfg.lua | 31 ++++++++++++++++++++++++++++++-<br data-darkosha-id="1:37" style="border-color: rgb(25, 25, 25) !important;">
1 file changed, 30 insertions(+), 1 deletion(-)<br data-darkosha-id="1:38" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:39" style="border-color: rgb(25, 25, 25) !important;">
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua<br data-darkosha-id="1:40" style="border-color: rgb(25, 25, 25) !important;">
index 79bde4d23..8ae72767d 100644<br data-darkosha-id="1:41" style="border-color: rgb(25, 25, 25) !important;">
--- a/src/box/lua/load_cfg.lua<br data-darkosha-id="1:42" style="border-color: rgb(25, 25, 25) !important;">
+++ b/src/box/lua/load_cfg.lua<br data-darkosha-id="1:43" style="border-color: rgb(25, 25, 25) !important;">
@@ -254,6 +254,32 @@ local dynamic_cfg = {<br data-darkosha-id="1:44" style="border-color: rgb(25, 25, 25) !important;">
net_msg_max = private.cfg_set_net_msg_max,<br data-darkosha-id="1:45" style="border-color: rgb(25, 25, 25) !important;">
}<br data-darkosha-id="1:46" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:47" style="border-color: rgb(25, 25, 25) !important;">
+--<br data-darkosha-id="1:48" style="border-color: rgb(25, 25, 25) !important;">
+-- For some options it is important in which order they are set.<br data-darkosha-id="1:49" style="border-color: rgb(25, 25, 25) !important;">
+-- For example, setting 'replication', including self, before<br data-darkosha-id="1:50" style="border-color: rgb(25, 25, 25) !important;">
+-- 'listen' makes no sense:<br data-darkosha-id="1:51" style="border-color: rgb(25, 25, 25) !important;">
+--<br data-darkosha-id="1:52" style="border-color: rgb(25, 25, 25) !important;">
+-- box.cfg{replication = {'localhost:3301'}, listen = 3301}<br data-darkosha-id="1:53" style="border-color: rgb(25, 25, 25) !important;">
+--<br data-darkosha-id="1:54" style="border-color: rgb(25, 25, 25) !important;">
+-- Replication won't be able to connect to a not being listened<br data-darkosha-id="1:55" style="border-color: rgb(25, 25, 25) !important;">
+-- port. In the table below for each option can be set a number.<br data-darkosha-id="1:56" style="border-color: rgb(25, 25, 25) !important;">
+-- An option is set before all other options having a bigger<br data-darkosha-id="1:57" style="border-color: rgb(25, 25, 25) !important;">
+-- number. Options without a number are installed after others in<br data-darkosha-id="1:58" style="border-color: rgb(25, 25, 25) !important;">
+-- an undefined order. The table works for reconfiguration only.<br data-darkosha-id="1:59" style="border-color: rgb(25, 25, 25) !important;">
+-- Order of first configuration is hardcoded in C and can't be<br data-darkosha-id="1:60" style="border-color: rgb(25, 25, 25) !important;">
+-- changed.<br data-darkosha-id="1:61" style="border-color: rgb(25, 25, 25) !important;">
+--<br data-darkosha-id="1:62" style="border-color: rgb(25, 25, 25) !important;">
+local dynamic_cfg_order = {<br data-darkosha-id="1:63" style="border-color: rgb(25, 25, 25) !important;">
+ listen = 100,<br data-darkosha-id="1:64" style="border-color: rgb(25, 25, 25) !important;">
+ replication = 200,<br data-darkosha-id="1:65" style="border-color: rgb(25, 25, 25) !important;">
+}<br data-darkosha-id="1:66" style="border-color: rgb(25, 25, 25) !important;">
+<br data-darkosha-id="1:67" style="border-color: rgb(25, 25, 25) !important;">
+local function sort_cfg_cb(l, r)<br data-darkosha-id="1:68" style="border-color: rgb(25, 25, 25) !important;">
+ l = dynamic_cfg_order[l] or math.huge<br data-darkosha-id="1:69" style="border-color: rgb(25, 25, 25) !important;">
+ r = dynamic_cfg_order[r] or math.huge<br data-darkosha-id="1:70" style="border-color: rgb(25, 25, 25) !important;">
+ return l < r<br data-darkosha-id="1:71" style="border-color: rgb(25, 25, 25) !important;">
+end<br data-darkosha-id="1:72" style="border-color: rgb(25, 25, 25) !important;">
+<br data-darkosha-id="1:73" style="border-color: rgb(25, 25, 25) !important;">
local dynamic_cfg_skip_at_load = {<br data-darkosha-id="1:74" style="border-color: rgb(25, 25, 25) !important;">
listen = true,<br data-darkosha-id="1:75" style="border-color: rgb(25, 25, 25) !important;">
memtx_memory = true,<br data-darkosha-id="1:76" style="border-color: rgb(25, 25, 25) !important;">
@@ -428,13 +454,16 @@ end<br data-darkosha-id="1:77" style="border-color: rgb(25, 25, 25) !important;">
local function reload_cfg(oldcfg, cfg)<br data-darkosha-id="1:78" style="border-color: rgb(25, 25, 25) !important;">
cfg = upgrade_cfg(cfg, translate_cfg)<br data-darkosha-id="1:79" style="border-color: rgb(25, 25, 25) !important;">
local newcfg = prepare_cfg(cfg, default_cfg, template_cfg, modify_cfg)<br data-darkosha-id="1:80" style="border-color: rgb(25, 25, 25) !important;">
+ local ordered_cfg = {}<br data-darkosha-id="1:81" style="border-color: rgb(25, 25, 25) !important;">
-- iterate over original table because prepare_cfg() may store NILs<br data-darkosha-id="1:82" style="border-color: rgb(25, 25, 25) !important;">
for key, val in pairs(cfg) do<br data-darkosha-id="1:83" style="border-color: rgb(25, 25, 25) !important;">
if dynamic_cfg[key] == nil and oldcfg[key] ~= val then<br data-darkosha-id="1:84" style="border-color: rgb(25, 25, 25) !important;">
box.error(box.error.RELOAD_CFG, key);<br data-darkosha-id="1:85" style="border-color: rgb(25, 25, 25) !important;">
end<br data-darkosha-id="1:86" style="border-color: rgb(25, 25, 25) !important;">
+ table.insert(ordered_cfg, key)<br data-darkosha-id="1:87" style="border-color: rgb(25, 25, 25) !important;">
end<br data-darkosha-id="1:88" style="border-color: rgb(25, 25, 25) !important;">
- for key in pairs(cfg) do<br data-darkosha-id="1:89" style="border-color: rgb(25, 25, 25) !important;">
+ table.sort(ordered_cfg, sort_cfg_cb)<br data-darkosha-id="1:90" style="border-color: rgb(25, 25, 25) !important;">
+ for _, key in pairs(ordered_cfg) do<br data-darkosha-id="1:91" style="border-color: rgb(25, 25, 25) !important;">
local val = newcfg[key]<br data-darkosha-id="1:92" style="border-color: rgb(25, 25, 25) !important;">
local oldval = oldcfg[key]<br data-darkosha-id="1:93" style="border-color: rgb(25, 25, 25) !important;">
if not compare_cfg(val, oldval) then<br data-darkosha-id="1:94" style="border-color: rgb(25, 25, 25) !important;">
-- <br data-darkosha-id="1:95" style="border-color: rgb(25, 25, 25) !important;">
2.21.0 (Apple Git-122)<br data-darkosha-id="1:96" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:97" style="border-color: rgb(25, 25, 25) !important;">
<br data-darkosha-id="1:98" style="border-color: rgb(25, 25, 25) !important;">
</div>
<base target="_self" href="https://e.mail.ru/" data-darkosha-id="1:99" style="border-color: rgb(25, 25, 25) !important;">
</div>
</div></blockquote></div></div></BODY></HTML>