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