From: "Евгений Заикин" <evgen4rave@gmail.com> To: tarantool-patches@freelists.org Subject: [tarantool-patches] [PATCH v2] Prohibit router/storage configuration from different fibers Date: Tue, 21 Aug 2018 12:27:07 +0300 [thread overview] Message-ID: <CAHwoe2XdQDoiR5X+hnN2wmruFddV-V4KqSfJm5C-9O_Uq6Szvg@mail.gmail.com> (raw) Adds prohibition of simultaneous router/storage configuration from multiple fibers. Fixes: #140 --- Ticket:https://github.com/tarantool/vshard/issues/140 Branch:https://github.com/tarantool/vshard/tree/rave4life/gh-140-prohibit-multiple-cfg Changes in v2: - separated test for router and storage - locker wrapper function moved to vshard.utils test/router/multi_fiber_cfg.result | 38 +++++++++++++++++++++++++ test/router/multi_fiber_cfg.test.lua | 12 ++++++++ test/storage/multi_fiber_cfg.result | 41 +++++++++++++++++++++++++++ test/storage/multi_fiber_cfg.test.lua | 13 +++++++++ vshard/router/init.lua | 6 ++-- vshard/storage/init.lua | 4 +-- vshard/util.lua | 17 +++++++++++ 7 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 test/router/multi_fiber_cfg.result create mode 100644 test/router/multi_fiber_cfg.test.lua create mode 100644 test/storage/multi_fiber_cfg.result create mode 100644 test/storage/multi_fiber_cfg.test.lua diff --git a/test/router/multi_fiber_cfg.result b/test/router/multi_fiber_cfg.result new file mode 100644 index 0000000..42a4055 --- /dev/null +++ b/test/router/multi_fiber_cfg.result @@ -0,0 +1,38 @@ +test_run = require('test_run').new() +--- +... +cfg = require('localcfg') +--- +... +cfg.memtx_memory = nil +--- +... +vshard = require('vshard') +--- +... +fiber = require('fiber') +--- +... +vshard.router.cfg(cfg) +--- +... +c = fiber.channel(2) +--- +... +f = function() fiber.create(function() local status, err = pcall(vshard.router.cfg, cfg) c:put(status and true or false) end) end +--- +... +f() +--- +... +f() +--- +... +c:get() +--- +- true +... +c:get() +--- +- true +... diff --git a/test/router/multi_fiber_cfg.test.lua b/test/router/multi_fiber_cfg.test.lua new file mode 100644 index 0000000..2d0a0c9 --- /dev/null +++ b/test/router/multi_fiber_cfg.test.lua @@ -0,0 +1,12 @@ +test_run = require('test_run').new() +cfg = require('localcfg') +cfg.memtx_memory = nil +vshard = require('vshard') +fiber = require('fiber') +vshard.router.cfg(cfg) +c = fiber.channel(2) +f = function() fiber.create(function() local status, err = pcall(vshard.router.cfg, cfg) c:put(status and true or false) end) end +f() +f() +c:get() +c:get() diff --git a/test/storage/multi_fiber_cfg.result b/test/storage/multi_fiber_cfg.result new file mode 100644 index 0000000..92fd06c --- /dev/null +++ b/test/storage/multi_fiber_cfg.result @@ -0,0 +1,41 @@ +test_run = require('test_run').new() +--- +... +cfg = {memtx_memory = nil, sharding = {}} +--- +... +cfg.sharding[box.info.cluster.uuid] = {replicas = {}} +--- +... +cfg.sharding[box.info.cluster.uuid].replicas[box.info.uuid] = {uri = 'storage:storage@127.0.0.1:3309', name = 'test_storage', master = true} +--- +... +vshard = require('vshard') +--- +... +fiber = require('fiber') +--- +... +c = fiber.channel(2) +--- +... +f = function() fiber.create(function() local status, err = pcall(vshard.storage.cfg, cfg, box.info.uuid) c:put(status and true or false) end) end +--- +... +f() +--- +... +f() +--- +... +c:get() +--- +- true +... +c:get() +--- +- true +... +cfg = nil +--- +... diff --git a/test/storage/multi_fiber_cfg.test.lua b/test/storage/multi_fiber_cfg.test.lua new file mode 100644 index 0000000..1a6cd39 --- /dev/null +++ b/test/storage/multi_fiber_cfg.test.lua @@ -0,0 +1,13 @@ +test_run = require('test_run').new() +cfg = {memtx_memory = nil, sharding = {}} +cfg.sharding[box.info.cluster.uuid] = {replicas = {}} +cfg.sharding[box.info.cluster.uuid].replicas[box.info.uuid] = {uri = 'storage:storage@127.0.0.1:3309', name = 'test_storage', master = true} +vshard = require('vshard') +fiber = require('fiber') +c = fiber.channel(2) +f = function() fiber.create(function() local status, err = pcall(vshard.storage.cfg, cfg, box.info.uuid) c:put(status and true or false) end) end +f() +f() +c:get() +c:get() +cfg = nil diff --git a/vshard/router/init.lua b/vshard/router/init.lua index 60ceafa..6b7a2c5 100644 --- a/vshard/router/init.lua +++ b/vshard/router/init.lua @@ -860,7 +860,7 @@ end local router_mt = { __index = { - cfg = function(router, cfg) return router_cfg(router, cfg, false) end, + cfg = function(router, cfg) return util.locker_func(router_cfg, router, cfg, false) end, info = router_info; buckets_info = router_buckets_info; call = router_call; @@ -934,7 +934,7 @@ end local function legacy_cfg(cfg) if M.static_router then -- Reconfigure. - router_cfg(M.static_router, cfg, false) + util.locker_func(router_cfg, M.static_router, cfg, false) else -- Create new static instance. local router, err = router_new(STATIC_ROUTER_NAME, cfg) @@ -959,7 +959,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) + util.locker_func(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 f9b8000..83f7343 100644 --- a/vshard/storage/init.lua +++ b/vshard/storage/init.lua @@ -1871,7 +1871,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) + util.locker_func(storage_cfg, M.current_cfg, M.this_replica.uuid, true) M.module_version = M.module_version + 1 end @@ -1908,7 +1908,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 util.locker_func(storage_cfg, cfg, uuid, false) end, info = storage_info, buckets_info = storage_buckets_info, buckets_count = storage_buckets_count, diff --git a/vshard/util.lua b/vshard/util.lua index 3afaa61..d52598b 100644 --- a/vshard/util.lua +++ b/vshard/util.lua @@ -11,6 +11,8 @@ if not M then M = { -- Latest versions of functions. reloadable_fiber_main_loop = nil, + cfg_counter = 0, + lock = fiber.channel(1), } rawset(_G, MODULE_INTERNALS, M) end @@ -134,10 +136,25 @@ local function async_task(delay, task, ...) fiber.create(sync_task, delay, task, ...) end +local function locker_func(f, ...) + M.lock:put(true) + if M.cfg_counter > 0 then + error('Error: cfg_counter > 0') + end + M.cfg_counter = M.cfg_counter + 1 + local status, err = pcall(f, ...) + M.cfg_counter = M.cfg_counter - 1 + M.lock:get() + if not status then + error(err) + end +end + return { tuple_extract_key = tuple_extract_key, reloadable_fiber_create = reloadable_fiber_create, generate_self_checker = generate_self_checker, async_task = async_task, + locker_func = locker_func, internal = M, } -- 2.17.1.windows.1
next reply other threads:[~2018-08-21 9:27 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-08-21 9:27 Евгений Заикин [this message] 2018-08-30 0:56 ` [tarantool-patches] " Vladislav Shpilevoy -- strict thread matches above, loose matches on Subject: below -- 2018-08-21 7:41 [tarantool-patches] " Евгений Заикин
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=CAHwoe2XdQDoiR5X+hnN2wmruFddV-V4KqSfJm5C-9O_Uq6Szvg@mail.gmail.com \ --to=evgen4rave@gmail.com \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH v2] Prohibit 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