Tarantool development patches archive
 help / color / mirror / Atom feed
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


             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