From: AKhatskevich <avkhatskevich@tarantool.org> To: v.shpilevoy@tarantool.org, tarantool-patches@freelists.org Subject: [tarantool-patches] [PATCH] Updata replicaser mt on package reload Date: Mon, 4 Jun 2018 19:27:55 +0300 [thread overview] Message-ID: <20180604162755.24952-1-avkhatskevich@tarantool.org> (raw) Update metatables of `replicaset` and `replica` objects on package reload in a way that updates metatables of already existing objects. Closes: #112 --- Branch: https://github.com/tarantool/vshard/tree/kh/gh-112-reload-mt Issue: https://github.com/tarantool/vshard/issues/112 Note: There is an idea that all objects should be recreated instead. test/router/reload.result | 43 +++++++++++++++++++++++++++++++++++++++++++ test/router/reload.test.lua | 14 ++++++++++++++ vshard/replicaset.lua | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/test/router/reload.result b/test/router/reload.result index 19a9ead..9c0a19b 100644 --- a/test/router/reload.result +++ b/test/router/reload.result @@ -174,6 +174,49 @@ vshard.router.module_version() check_reloaded() --- ... +assert(rawget(_G, '__module_vshard_replicaset') ~= nil) +--- +- true +... +_, replicaset = next(vshard.router.internal.replicasets) +--- +... +old_mt_method = getmetatable(replicaset).__index.call +--- +... +M = require('vshard.replicaset').internal +--- +... +M.errinj.ERRINJ_RELOAD = true +--- +... +package.loaded["vshard.replicaset"] = nil +--- +... +ok, msg = pcall(require, 'vshard.replicaset') +--- +... +assert(ok == false) +--- +- true +... +old_mt_method == getmetatable(replicaset).__index.call +--- +- true +... +M.errinj.ERRINJ_RELOAD = false +--- +... +package.loaded["vshard.replicaset"] = nil +--- +... +_ = require('vshard.replicaset') +--- +... +old_mt_method == getmetatable(replicaset).__index.call +--- +- false +... test_run:switch('default') --- - true diff --git a/test/router/reload.test.lua b/test/router/reload.test.lua index 6e21b74..cdb5d50 100644 --- a/test/router/reload.test.lua +++ b/test/router/reload.test.lua @@ -86,6 +86,20 @@ _ = require('vshard.router') vshard.router.module_version() check_reloaded() +assert(rawget(_G, '__module_vshard_replicaset') ~= nil) +_, replicaset = next(vshard.router.internal.replicasets) +old_mt_method = getmetatable(replicaset).__index.call +M = require('vshard.replicaset').internal +M.errinj.ERRINJ_RELOAD = true +package.loaded["vshard.replicaset"] = nil +ok, msg = pcall(require, 'vshard.replicaset') +assert(ok == false) +old_mt_method == getmetatable(replicaset).__index.call +M.errinj.ERRINJ_RELOAD = false +package.loaded["vshard.replicaset"] = nil +_ = require('vshard.replicaset') +old_mt_method == getmetatable(replicaset).__index.call + test_run:switch('default') test_run:cmd('stop server router_1') test_run:cmd('cleanup server router_1') diff --git a/vshard/replicaset.lua b/vshard/replicaset.lua index 7fcf2df..62a9b9e 100644 --- a/vshard/replicaset.lua +++ b/vshard/replicaset.lua @@ -50,6 +50,21 @@ local luri = require('uri') local ffi = require('ffi') local gsc = require('vshard.util').generate_self_checker +local M = rawget(_G, '__module_vshard_replicaset') +if not M then + -- + -- The module is loaded for the first time. + -- + M = { + errinj = { + ERRINJ_RELOAD = false, + }, + -- Cache metatables of old objects to update them. + replicaset_mt = {}, + replica_mt = {}, + } +end + -- -- on_connect() trigger for net.box -- @@ -383,7 +398,7 @@ local replicaset_mt = { -- local index = {} for name, func in pairs(replicaset_mt.__index) do - index[name] = gsc("replicaset", name, replicaset_mt, func) + index[name] = gsc("replicaset", name, M.replicaset_mt, func) end replicaset_mt.__index = index @@ -408,7 +423,7 @@ local replica_mt = { } index = {} for name, func in pairs(replica_mt.__index) do - index[name] = gsc("replica", name, replica_mt, func) + index[name] = gsc("replica", name, M.replica_mt, func) end replica_mt.__index = index @@ -523,7 +538,7 @@ local function buildall(sharding_cfg, old_replicasets) weight = replicaset.weight, bucket_count = 0, lock = replicaset.lock, - }, replicaset_mt) + }, M.replicaset_mt) local priority_list = {} for replica_uuid, replica in pairs(replicaset.replicas) do local old_replica = old_replicaset and @@ -536,7 +551,7 @@ local function buildall(sharding_cfg, old_replicasets) zone = replica.zone, net_timeout = consts.CALL_TIMEOUT_MIN, net_sequential_ok = 0, net_sequential_fail = 0, down_ts = curr_ts, old_replica = old_replica, - }, replica_mt) + }, M.replica_mt) new_replicaset.replicas[replica_uuid] = new_replica if replica.master then new_replicaset.master = new_replica @@ -592,8 +607,24 @@ local function wait_masters_connect(replicasets) end end +if M.errinj.ERRINJ_RELOAD then + error('Error injection: reload') +end + +-- +-- In case the module is loaded correctly, do externally-visible changes. +-- +if not rawget(_G, '__module_vshard_replicaset') then + rawset(_G, '__module_vshard_replicaset', M) +end +M.replicaset_mt.__index = replicaset_mt.__index +M.replicaset_mt.__tostring = replicaset_mt.__tostring +M.replica_mt.__index = replica_mt.__index +M.replica_mt.__tostring = replica_mt.__tostring + return { buildall = buildall, calculate_etalon_balance = cluster_calculate_etalon_balance, + internal = M, wait_masters_connect = wait_masters_connect, } -- 2.14.1
next reply other threads:[~2018-06-04 16:28 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-04 16:27 AKhatskevich [this message] 2018-06-04 18:18 ` [tarantool-patches] " Vladislav Shpilevoy
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=20180604162755.24952-1-avkhatskevich@tarantool.org \ --to=avkhatskevich@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH] Updata replicaser mt on package reload' \ /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