From: "Евгений Заикин" <dmarc-noreply@freelists.org> (Redacted sender "evgeniy19872004" for DMARC) To: tarantool-patches <tarantool-patches@freelists.org> Subject: [tarantool-patches] [PATCH] vshard: added prohibition of multiple router/storage configuration from different fibers Date: Mon, 13 Aug 2018 12:41:20 +0300 [thread overview] Message-ID: <1534153280.58559115@f426.i.mail.ru> (raw) Adds prohibition of multiple router/storage configuration from different fibers Fixes: #140 --- Ticket:https://github.com/tarantool/vshard/issues/140 Branch:rave4life/gh-140-prohibit-multiple-cfg test/misc/vshard_multi_fiber_cfg.result | 53 +++++++++++++++++++++++ test/misc/vshard_multi_fiber_cfg.test.lua | 21 +++++++++ vshard/router/init.lua | 20 +++++++-- vshard/storage/init.lua | 18 +++++++- 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 test/misc/vshard_multi_fiber_cfg.result create mode 100644 test/misc/vshard_multi_fiber_cfg.test.lua diff --git a/test/misc/vshard_multi_fiber_cfg.result b/test/misc/vshard_multi_fiber_cfg.result new file mode 100644 index 0000000..21121eb --- /dev/null +++ b/test/misc/vshard_multi_fiber_cfg.result @@ -0,0 +1,53 @@ +test_run = require('test_run').new() +--- +... +cfg.weights = nil +--- +... +sample_replica_id = '9519e546-e39b-4db8-a3bb-66a59fdea9fc' +--- +... +vshard = require('vshard') +--- +... +-- gh-140 - Prohibit vshard.router/storage.cfg from multiple fibers +fiber = require('fiber') +--- +... +c = fiber.channel(2) +--- +... +sf = function() fiber.create(function() pcall(vshard.storage.cfg, cfg, sample_replica_id, false) c:put(true) end) end +--- +... +sf() +--- +... +sf() +--- +... +c:get() +--- +- true +... +c:get() +--- +- true +... +rf = function() fiber.create(function() pcall(vshard.router.cfg, cfg) c:put(true) end) end +--- +... +rf() +--- +... +rf() +--- +... +c:get() +--- +- true +... +c:get() +--- +- true +... diff --git a/test/misc/vshard_multi_fiber_cfg.test.lua b/test/misc/vshard_multi_fiber_cfg.test.lua new file mode 100644 index 0000000..fd1aeda --- /dev/null +++ b/test/misc/vshard_multi_fiber_cfg.test.lua @@ -0,0 +1,21 @@ +test_run = require('test_run').new() + +cfg.weights = nil + +sample_replica_id = '9519e546-e39b-4db8-a3bb-66a59fdea9fc' + +vshard = require('vshard') + +-- gh-140 - Prohibit vshard.router/storage.cfg from multiple fibers +fiber = require('fiber') +c = fiber.channel(2) +sf = function() fiber.create(function() pcall(vshard.storage.cfg, cfg, sample_replica_id, false) c:put(true) end) end +sf() +sf() +c:get() +c:get() +rf = function() fiber.create(function() pcall(vshard.router.cfg, cfg) c:put(true) end) end +rf() +rf() +c:get() +c:get() diff --git a/vshard/router/init.lua b/vshard/router/init.lua index 971d830..de0a143 100644 --- a/vshard/router/init.lua +++ b/vshard/router/init.lua @@ -2,6 +2,20 @@ local log = require('log') local lfiber = require('fiber') local table_new = require('table.new') +-- Function decorator that is used to prevent router.cfg() from +-- being called concurrently by different fibers. +local lock = lfiber.channel(1) +local function locked(f) + return function(...) + lock:put(true) + local status, err = pcall(f, ...) + lock:get() + if not status then + error(err) + end + end +end + local MODULE_INTERNALS = '__module_vshard_router' -- Reload requirements, in case this module is reloaded manually. if rawget(_G, MODULE_INTERNALS) then @@ -856,7 +870,7 @@ end local router_mt = { __index = { - cfg = function(router, cfg) return router_cfg(router, cfg, false) end, + cfg = function(router, cfg) return locked(router_cfg)(router, cfg, false) end, info = router_info; buckets_info = router_buckets_info; call = router_call; @@ -930,7 +944,7 @@ end local function legacy_cfg(cfg) if M.static_router then -- Reconfigure. - router_cfg(M.static_router, cfg, false) + locked(router_cfg)(M.static_router, cfg, false) else -- Create new static instance. local router, err = router_new(STATIC_ROUTER_NAME, cfg) @@ -955,7 +969,7 @@ if not rawget(_G, MODULE_INTERNALS) then rawset(_G, MODULE_INTERNALS, M) else for _, router in pairs(M.routers) do - router_cfg(router, router.current_cfg, true) + locked(router_cfg)(router, router.current_cfg, true) setmetatable(router, router_mt) end if M.static_router then diff --git a/vshard/storage/init.lua b/vshard/storage/init.lua index b1ecb7b..d848145 100644 --- a/vshard/storage/init.lua +++ b/vshard/storage/init.lua @@ -4,6 +4,20 @@ local lfiber = require('fiber') local netbox = require('net.box') -- for net.box:self() local trigger = require('internal.trigger') +-- Function decorator that is used to prevent storage.cfg() from +-- being called concurrently by different fibers. +local lock = lfiber.channel(1) +local function locked(f) + return function(...) + lock:put(true) + local status, err = pcall(f, ...) + lock:get() + if not status then + error(err) + end + end +end + local MODULE_INTERNALS = '__module_vshard_storage' -- Reload requirements, in case this module is reloaded manually. if rawget(_G, MODULE_INTERNALS) then @@ -1866,7 +1880,7 @@ if not rawget(_G, MODULE_INTERNALS) then rawset(_G, MODULE_INTERNALS, M) else reload_evolution.upgrade(M) - storage_cfg(M.current_cfg, M.this_replica.uuid, true) + locked(storage_cfg)(M.current_cfg, M.this_replica.uuid, true) M.module_version = M.module_version + 1 end @@ -1905,7 +1919,7 @@ return { rebalancing_is_in_progress = rebalancing_is_in_progress, recovery_wakeup = recovery_wakeup, call = storage_call, - cfg = function(cfg, uuid) return storage_cfg(cfg, uuid, false) end, + cfg = function(cfg, uuid) return locked(storage_cfg)(cfg, uuid, false) end, info = storage_info, buckets_info = storage_buckets_info, buckets_count = storage_buckets_count, -- 2.17.1.windows.1
next reply other threads:[~2018-08-13 9:41 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-08-13 9:41 Евгений Заикин [this message] 2018-08-14 21:22 ` [tarantool-patches] " Vladislav Shpilevoy 2018-08-14 21:24 ` 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=1534153280.58559115@f426.i.mail.ru \ --to=dmarc-noreply@freelists.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH] vshard: added prohibition of multiple router/storage configuration from different fibers' \ /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