Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: AKhatskevich <avkhatskevich@tarantool.org>,
	tarantool-patches@freelists.org
Subject: [tarantool-patches] Re: [PATCH] Updata replicaser mt on package reload
Date: Mon, 4 Jun 2018 21:18:19 +0300	[thread overview]
Message-ID: <f1d965f7-22e0-39b1-0dd3-0adf1c4c85c7@tarantool.org> (raw)
In-Reply-To: <20180604162755.24952-1-avkhatskevich@tarantool.org>

Thanks for the patch! Verbally we have decided to make this patch
more system. Alexey will rework the way how replica and replicaset
objects are built in replicaset.buildall method. It will allow to
reconfig and reload with no replica/replicaset objects recreation,
but with reset.

On 04/06/2018 19:27, AKhatskevich wrote:
> 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,
>   }
> 

      reply	other threads:[~2018-06-04 18:18 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-04 16:27 [tarantool-patches] " AKhatskevich
2018-06-04 18:18 ` Vladislav Shpilevoy [this message]

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=f1d965f7-22e0-39b1-0dd3-0adf1c4c85c7@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=avkhatskevich@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='[tarantool-patches] Re: [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