From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 323DC267FC for ; Fri, 22 Jun 2018 17:44:00 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Kba-aS0BrIzT for ; Fri, 22 Jun 2018 17:44:00 -0400 (EDT) Received: from smtp36.i.mail.ru (smtp36.i.mail.ru [94.100.177.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id B510A210A0 for ; Fri, 22 Jun 2018 17:43:59 -0400 (EDT) From: AKhatskevich Subject: [tarantool-patches] [PATCH 3/3] Introduce destroy module feature Date: Sat, 23 Jun 2018 00:43:35 +0300 Message-Id: In-Reply-To: References: In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org, v.shpilevoy@tarantool.org Introduce functions: * vshard.router.destroy() * vshard.storage.destroy() Those functions: * close connections * stop background fibers * delete vshard spaces * delete vshard funcitons * delete `once` metadate Closes #121 --- test/lua_libs/util.lua | 34 +++++++++++ test/router/destroy.result | 108 ++++++++++++++++++++++++++++++++++ test/router/destroy.test.lua | 39 +++++++++++++ test/storage/destroy.result | 132 ++++++++++++++++++++++++++++++++++++++++++ test/storage/destroy.test.lua | 51 ++++++++++++++++ vshard/router/init.lua | 22 +++++++ vshard/storage/init.lua | 70 +++++++++++++++++----- 7 files changed, 440 insertions(+), 16 deletions(-) create mode 100644 test/router/destroy.result create mode 100644 test/router/destroy.test.lua create mode 100644 test/storage/destroy.result create mode 100644 test/storage/destroy.test.lua diff --git a/test/lua_libs/util.lua b/test/lua_libs/util.lua index f2d3b48..ce0ea67 100644 --- a/test/lua_libs/util.lua +++ b/test/lua_libs/util.lua @@ -69,9 +69,43 @@ local function wait_master(test_run, replicaset, master) log.info('Slaves are connected to a master "%s"', master) end +function vshard_fiber_list() + -- Flush jit traces to prevent them from + -- keeping its upvalues in memory. + jit.flush() + collectgarbage() + -- Give a fiber time to clean itself. + fiber.sleep(0.05) + local fibers = fiber.info() + local non_vshard_patterns = { + '^console', + 'feedback_daemon$', + '^checkpoint_daemon$', + '^main$', + '^memtx%.gc$', + '^vinyl%.scheduler$', + } + local names = {} + for _, fib in pairs(fibers) do + local add = true + for _, pattern in pairs(non_vshard_patterns) do + if fib.name:match(pattern) then + add = false + break + end + end + if add then + table.insert(names, fib.name) + end + end + table.sort(names) + return names +end; + return { check_error = check_error, shuffle_masters = shuffle_masters, collect_timeouts = collect_timeouts, wait_master = wait_master, + vshard_fiber_list = vshard_fiber_list, } diff --git a/test/router/destroy.result b/test/router/destroy.result new file mode 100644 index 0000000..48ba661 --- /dev/null +++ b/test/router/destroy.result @@ -0,0 +1,108 @@ +test_run = require('test_run').new() +--- +... +netbox = require('net.box') +--- +... +fiber = require('fiber') +--- +... +REPLICASET_1 = { 'storage_1_a', 'storage_1_b' } +--- +... +REPLICASET_2 = { 'storage_2_a', 'storage_2_b' } +--- +... +test_run:create_cluster(REPLICASET_1, 'storage') +--- +... +test_run:create_cluster(REPLICASET_2, 'storage') +--- +... +util = require('util') +--- +... +util.wait_master(test_run, REPLICASET_1, 'storage_1_a') +--- +... +util.wait_master(test_run, REPLICASET_2, 'storage_2_a') +--- +... +test_run:cmd("create server router_1 with script='router/router_1.lua'") +--- +- true +... +test_run:cmd("start server router_1") +--- +- true +... +_ = test_run:cmd("switch router_1") +--- +... +util = require('util') +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function wait_fibers_exit() + while #util.vshard_fiber_list() > 0 do + sleep(0.05) + end +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +-- Validate destroy finction by fiber_list. +-- Netbox fibers are deleted after replicas by GC. +util.vshard_fiber_list() +--- +- - 127.0.0.1:3301 (net.box) + - 127.0.0.1:3302 (net.box) + - 127.0.0.1:3303 (net.box) + - 127.0.0.1:3304 (net.box) + - discovery_fiber + - vshard.failover +... +vshard.router.destroy() +--- +... +wait_fibers_exit() +--- +... +package.loaded['vshard.router'] = nil +--- +... +vshard.router = require('vshard.router') +--- +... +vshard.router.cfg(cfg) +--- +... +util.vshard_fiber_list() +--- +- - 127.0.0.1:3301 (net.box) + - 127.0.0.1:3302 (net.box) + - 127.0.0.1:3303 (net.box) + - 127.0.0.1:3304 (net.box) + - discovery_fiber + - vshard.failover +... +_ = test_run:cmd("switch default") +--- +... +test_run:cmd('stop server router_1') +--- +- true +... +test_run:cmd('cleanup server router_1') +--- +- true +... +test_run:drop_cluster(REPLICASET_2) +--- +... diff --git a/test/router/destroy.test.lua b/test/router/destroy.test.lua new file mode 100644 index 0000000..1f972bd --- /dev/null +++ b/test/router/destroy.test.lua @@ -0,0 +1,39 @@ +test_run = require('test_run').new() +netbox = require('net.box') +fiber = require('fiber') + +REPLICASET_1 = { 'storage_1_a', 'storage_1_b' } +REPLICASET_2 = { 'storage_2_a', 'storage_2_b' } + +test_run:create_cluster(REPLICASET_1, 'storage') +test_run:create_cluster(REPLICASET_2, 'storage') +util = require('util') +util.wait_master(test_run, REPLICASET_1, 'storage_1_a') +util.wait_master(test_run, REPLICASET_2, 'storage_2_a') +test_run:cmd("create server router_1 with script='router/router_1.lua'") +test_run:cmd("start server router_1") + +_ = test_run:cmd("switch router_1") +util = require('util') +test_run:cmd("setopt delimiter ';'") +function wait_fibers_exit() + while #util.vshard_fiber_list() > 0 do + sleep(0.05) + end +end; +test_run:cmd("setopt delimiter ''"); + +-- Validate destroy finction by fiber_list. +-- Netbox fibers are deleted after replicas by GC. +util.vshard_fiber_list() +vshard.router.destroy() +wait_fibers_exit() +package.loaded['vshard.router'] = nil +vshard.router = require('vshard.router') +vshard.router.cfg(cfg) +util.vshard_fiber_list() + +_ = test_run:cmd("switch default") +test_run:cmd('stop server router_1') +test_run:cmd('cleanup server router_1') +test_run:drop_cluster(REPLICASET_2) diff --git a/test/storage/destroy.result b/test/storage/destroy.result new file mode 100644 index 0000000..23ec6bd --- /dev/null +++ b/test/storage/destroy.result @@ -0,0 +1,132 @@ +test_run = require('test_run').new() +--- +... +REPLICASET_1 = { 'storage_1_a', 'storage_1_b' } +--- +... +REPLICASET_2 = { 'storage_2_a', 'storage_2_b' } +--- +... +test_run:create_cluster(REPLICASET_1, 'storage') +--- +... +test_run:create_cluster(REPLICASET_2, 'storage') +--- +... +util = require('util') +--- +... +util.wait_master(test_run, REPLICASET_1, 'storage_1_a') +--- +... +util.wait_master(test_run, REPLICASET_2, 'storage_2_a') +--- +... +_ = test_run:cmd("switch storage_1_a") +--- +... +util = require('util') +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function wait_fibers_exit() + while #util.vshard_fiber_list() > 0 do + sleep(0.05) + end +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +-- Storage is configured. +-- Establish net.box connection. +_, rs = next(vshard.storage.internal.replicasets) +--- +... +rs:callro('echo', {'some data'}) +--- +- some data +- null +- null +... +rs = nil +--- +... +-- Validate destroy finction by fiber_list. +-- Netbox fibers are deleted after replicas by GC. +util.vshard_fiber_list() +--- +- - 127.0.0.1:3303 (net.box) + - vshard.gc + - vshard.recovery +... +box.schema.user.exists('storage') == true +--- +- true +... +box.space._bucket ~= nil +--- +- true +... +-- Destroy storage. +vshard.storage.destroy() +--- +... +wait_fibers_exit() +--- +... +box.space._bucket == nil +--- +- true +... +-- Reconfigure storage. +-- gh-52: Allow use existing user. +box.schema.user.exists('storage') == true +--- +- true +... +package.loaded['vshard.storage'] = nil +--- +... +vshard.storage = require('vshard.storage') +--- +... +vshard.storage.cfg(cfg, names['storage_1_a']) +--- +... +_, rs = next(vshard.storage.internal.replicasets) +--- +... +rs:callro('echo', {'some data'}) +--- +- some data +- null +- null +... +rs = nil +--- +... +box.space._bucket ~= nil +--- +- true +... +util.vshard_fiber_list() +--- +- - 127.0.0.1:3303 (net.box) + - vshard.gc + - vshard.recovery +... +_ = test_run:cmd("switch default") +--- +... +test_run:drop_cluster(REPLICASET_2) +--- +... +test_run:drop_cluster(REPLICASET_1) +--- +... diff --git a/test/storage/destroy.test.lua b/test/storage/destroy.test.lua new file mode 100644 index 0000000..156b76e --- /dev/null +++ b/test/storage/destroy.test.lua @@ -0,0 +1,51 @@ +test_run = require('test_run').new() + +REPLICASET_1 = { 'storage_1_a', 'storage_1_b' } +REPLICASET_2 = { 'storage_2_a', 'storage_2_b' } + +test_run:create_cluster(REPLICASET_1, 'storage') +test_run:create_cluster(REPLICASET_2, 'storage') +util = require('util') +util.wait_master(test_run, REPLICASET_1, 'storage_1_a') +util.wait_master(test_run, REPLICASET_2, 'storage_2_a') + +_ = test_run:cmd("switch storage_1_a") +util = require('util') +test_run:cmd("setopt delimiter ';'") +function wait_fibers_exit() + while #util.vshard_fiber_list() > 0 do + sleep(0.05) + end +end; +test_run:cmd("setopt delimiter ''"); + +-- Storage is configured. +-- Establish net.box connection. +_, rs = next(vshard.storage.internal.replicasets) +rs:callro('echo', {'some data'}) +rs = nil +-- Validate destroy finction by fiber_list. +-- Netbox fibers are deleted after replicas by GC. +util.vshard_fiber_list() +box.schema.user.exists('storage') == true +box.space._bucket ~= nil +-- Destroy storage. +vshard.storage.destroy() +wait_fibers_exit() +box.space._bucket == nil + +-- Reconfigure storage. +-- gh-52: Allow use existing user. +box.schema.user.exists('storage') == true +package.loaded['vshard.storage'] = nil +vshard.storage = require('vshard.storage') +vshard.storage.cfg(cfg, names['storage_1_a']) +_, rs = next(vshard.storage.internal.replicasets) +rs:callro('echo', {'some data'}) +rs = nil +box.space._bucket ~= nil +util.vshard_fiber_list() + +_ = test_run:cmd("switch default") +test_run:drop_cluster(REPLICASET_2) +test_run:drop_cluster(REPLICASET_1) diff --git a/vshard/router/init.lua b/vshard/router/init.lua index 21093e5..da8e49e 100644 --- a/vshard/router/init.lua +++ b/vshard/router/init.lua @@ -33,6 +33,27 @@ if not M then } end +-- +-- Destroy router module. +-- +local function destroy() + local MODULE_INTERNALS = '__module_vshard_router' + assert(rawget(_G, MODULE_INTERNALS), 'Already destroyed') + local bg_fibers = { + 'failover_fiber', + 'discovery_fiber', + } + for _, fib_name in pairs(bg_fibers) do + if M[fib_name] then + M[fib_name]:cancel() + M[fib_name] = nil + end + end + vshard.router.internal = nil + rawset(_G, MODULE_INTERNALS, nil) + M = nil +end + -- Set a replicaset by container of a bucket. local function bucket_set(bucket_id, replicaset) assert(replicaset) @@ -792,6 +813,7 @@ return { sync = router_sync; bootstrap = cluster_bootstrap; bucket_discovery = bucket_discovery; + destroy = destroy, discovery_wakeup = discovery_wakeup; internal = M; module_version = function() return M.module_version end; diff --git a/vshard/storage/init.lua b/vshard/storage/init.lua index 059e705..ac37163 100644 --- a/vshard/storage/init.lua +++ b/vshard/storage/init.lua @@ -148,6 +148,22 @@ local function create_user(username, password) {if_not_exists = true}) end +local storage_api = { + 'vshard.storage.sync', + 'vshard.storage.call', + 'vshard.storage.bucket_force_create', + 'vshard.storage.bucket_force_drop', + 'vshard.storage.bucket_collect', + 'vshard.storage.bucket_send', + 'vshard.storage.bucket_recv', + 'vshard.storage.bucket_stat', + 'vshard.storage.buckets_count', + 'vshard.storage.buckets_info', + 'vshard.storage.buckets_discovery', + 'vshard.storage.rebalancer_request_state', + 'vshard.storage.rebalancer_apply_routes', +} + local function storage_schema_v1(username, password) log.info("Initializing schema") create_user(username, password) @@ -161,22 +177,6 @@ local function storage_schema_v1(username, password) bucket:create_index('pk', {parts = {'id'}}) bucket:create_index('status', {parts = {'status'}, unique = false}) - local storage_api = { - 'vshard.storage.sync', - 'vshard.storage.call', - 'vshard.storage.bucket_force_create', - 'vshard.storage.bucket_force_drop', - 'vshard.storage.bucket_collect', - 'vshard.storage.bucket_send', - 'vshard.storage.bucket_recv', - 'vshard.storage.bucket_stat', - 'vshard.storage.buckets_count', - 'vshard.storage.buckets_info', - 'vshard.storage.buckets_discovery', - 'vshard.storage.rebalancer_request_state', - 'vshard.storage.rebalancer_apply_routes', - } - for _, name in ipairs(storage_api) do box.schema.func.create(name, {setuid = true}) box.schema.user.grant(username, 'execute', 'function', name) @@ -207,6 +207,43 @@ local function on_master_enable(...) end end +-------------------------------------------------------------------------------- +-- Destroy +-------------------------------------------------------------------------------- + +-- +-- Destroy storage module. +-- +local function destroy() + local MODULE_INTERNALS = '__module_vshard_storage' + assert(rawget(_G, MODULE_INTERNALS), 'Already destroyed') + box.space._bucket:drop() + for _, name in ipairs(storage_api) do + box.schema.func.drop(name) + end + local bg_fibers = { + 'recovery_fiber', + 'collect_bucket_garbage_fiber', + 'rebalancer_applier_fiber', + 'rebalancer_fiber', + } + for _, fib_name in pairs(bg_fibers) do + if M[fib_name] then + M[fib_name]:cancel() + M[fib_name] = nil + end + end + local box_cfg = table.deepcopy(box.cfg) + box_cfg.replication = nil + box_cfg.read_only = nil + box.cfg(box_cfg) + vshard.storage.internal = nil + box.space._schema:delete{'oncevshard:storage:1'} + rawset(_G, MODULE_INTERNALS, nil) + M = nil + box.snapshot() +end + -------------------------------------------------------------------------------- -- Recovery -------------------------------------------------------------------------------- @@ -1844,6 +1881,7 @@ return { bucket_pin = bucket_pin, bucket_unpin = bucket_unpin, bucket_delete_garbage = bucket_delete_garbage, + destroy = destroy, garbage_collector_wakeup = garbage_collector_wakeup, rebalancer_wakeup = rebalancer_wakeup, rebalancer_apply_routes = rebalancer_apply_routes, -- 2.14.1