From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org, AKhatskevich <avkhatskevich@tarantool.org> Subject: [tarantool-patches] Re: [PATCH 3/3] Introduce multiple routers feature Date: Wed, 1 Aug 2018 21:43:37 +0300 [thread overview] Message-ID: <30ab88fc-fba0-11d8-254c-385e59caead7@tarantool.org> (raw) In-Reply-To: <a3f2c4aac83b870da2fd21092cbc459584851fd0.1533054045.git.avkhatskevich@tarantool.org> Thanks for the patch! See 10 comments below. On 31/07/2018 19:25, AKhatskevich wrote: > Key points: > * Old `vshard.router.some_method()` api is preserved. > * Add `vshard.router.new(name, cfg)` method which returns a new router. > * Each router has its own: > 1. name > 2. background fibers > 3. attributes (route_map, replicasets, outdate_delay...) > * Module reload reloads all configured routers. > * `cfg` reconfigures a single router. > * All routers share the same box configuration. The last passed config > overrides the global config. > * Multiple router instances can be connected to the same cluster. > * By now, a router cannot be destroyed. > > Extra changes: > * Add `data` parameter to `reloadable_fiber_create` function. > > Closes #130 > ---> diff --git a/test/multiple_routers/multiple_routers.result b/test/multiple_routers/multiple_routers.result > new file mode 100644 > index 0000000..33f4034 > --- /dev/null > +++ b/test/multiple_routers/multiple_routers.result > @@ -0,0 +1,226 @@ > +-- Reconfigure one of routers do not affect the others. > +routers[3]:cfg(configs.cfg_1) 1. You did not change configs.cfg_1 so it is not reconfig actually. Please, change something to check that the parameter affects one router and does not affect others. 2. Please, add a test on an ability to get the static router into a variable and use it like others. It should be possible to hide distinctions between static and other routers. Like this: r1 = vshard.router.static r2 = vshard.router.new(...) do_something_with_router(r1) do_something_with_router(r2) Here do_something_with_router() is unaware of whether the router is static or not. > diff --git a/vshard/router/init.lua b/vshard/router/init.lua > index 3e127cb..7569baf 100644 > --- a/vshard/router/init.lua > +++ b/vshard/router/init.lua > @@ -257,13 +272,13 @@ local function router_call(bucket_id, mode, func, args, opts) > -- but already is executed on storages. > while lfiber.time() <= tend do > lfiber.sleep(0.05) > - replicaset = M.replicasets[err.destination] > + replicaset = router.replicasets[err.destination] > if replicaset then > goto replicaset_is_found > end > end > else > - replicaset = bucket_set(bucket_id, replicaset.uuid) > + replicaset = bucket_set(router, bucket_id, replicaset.uuid) 3. Out of 80 symbols. > lfiber.yield() > -- Protect against infinite cycle in a > -- case of broken cluster, when a bucket > @@ -488,9 +503,14 @@ end > -- Configuration > -------------------------------------------------------------------------------- > > -local function router_cfg(cfg) > - local vshard_cfg, box_cfg = lcfg.check(cfg, M.current_cfg) > - if not M.replicasets then > +-- Types of configuration. > +CFG_NEW = 'new' > +CFG_RELOAD = 'reload' > +CFG_RECONFIGURE = 'reconfigure' 4. Last two values are never used in router_cfg(). The first is used for logging only and can be checked as it was before with no explicit passing. > + > +local function router_cfg(router, cfg, cfg_type) > + local vshard_cfg, box_cfg = lcfg.check(cfg, router.current_cfg) > + if cfg_type == CFG_NEW then > log.info('Starting router configuration') > else > log.info('Starting router reconfiguration') > @@ -512,44 +532,53 @@ local function router_cfg(cfg) > + > +local function updage_lua_gc_state() 5. This function is not needed actually. On router_new() the only thing that can change is start of the gc fiber if the new router has the flag and the gc is not started now. It can be checked by a simple 'if' with no full-scan of all routers. On reload it is not possible to change configuration, so the gc state can not be changed and does not need an update. Even if it could be changed, you already iterate over routers on reload to call router_cfg and can collect their flags along side. The next point is that it is not possible now to manage the gc via simple :cfg() call. You do nothing with gc when router_cfg is called directly. And that produces a question - why do your tests pass if so? The possible solution - keep a counter of set lua gc flags overall routers in M. On each cfg you update the counter if the value is changed. If it was 0 and become > 0, then you start gc. If it was > 0 and become 0, then you stop gc. No routers iteration at all. > + local lua_gc = false > + for _, xrouter in pairs(M.routers) do > + if xrouter.collect_lua_garbage then > + lua_gc = true > + end > + end > + lua_gc.set_state(lua_gc, consts.COLLECT_LUA_GARBAGE_INTERVAL) > end > > @@ -803,6 +833,93 @@ if M.errinj.ERRINJ_RELOAD then > error('Error injection: reload') > end > > +-------------------------------------------------------------------------------- > +-- Managing router instances > +-------------------------------------------------------------------------------- > + > +local function cfg_reconfigure(router, cfg) > + return router_cfg(router, cfg, CFG_RECONFIGURE) > +end > + > +local router_mt = { > + __index = { > + cfg = cfg_reconfigure; > + info = router_info; > + buckets_info = router_buckets_info; > + call = router_call; > + callro = router_callro; > + callrw = router_callrw; > + route = router_route; > + routeall = router_routeall; > + bucket_id = router_bucket_id; > + bucket_count = router_bucket_count; > + sync = router_sync; > + bootstrap = cluster_bootstrap; > + bucket_discovery = bucket_discovery; > + discovery_wakeup = discovery_wakeup; > + } > +} > + > +-- Table which represents this module. > +local module = {} > + > +local function export_static_router_attributes() > + -- This metatable bypasses calls to a module to the static_router. > + local module_mt = {__index = {}} > + for method_name, method in pairs(router_mt.__index) do > + module_mt.__index[method_name] = function(...) > + if M.static_router then > + return method(M.static_router, ...) > + else > + error('Static router is not configured') 6. This should not be all-time check. You should initialize the static router metatable with only errors. On the first cfg you reset the metatable to always use regular methods. But anyway this code is unreachable. See below in the comment 10 why it is so. > + end > + end > + end > + setmetatable(module, module_mt) > + -- Make static_router attributes accessible form > + -- vshard.router.internal. > + local M_static_router_attributes = { > + name = true, > + replicasets = true, > + route_map = true, > + total_bucket_count = true, > + } 7. I saw in the tests that you are using vshard.router.internal.static_router instead. Please, remove M_static_router_attributes then. > + setmetatable(M, { > + __index = function(M, key) > + return M.static_router[key] > + end > + }) > +end > + > +local function router_new(name, cfg) > + assert(type(name) == 'string' and type(cfg) == 'table', > + 'Wrong argument type. Usage: vshard.router.new(name, cfg).') 8. As I said before, do not use assertions for usage checks in public API. Use 'if wrong_usage then error(...) end'. > + if M.routers[name] then > + return nil, string.format('Router with name %s already exists', name) > + end > + local router = table.deepcopy(ROUTER_TEMPLATE) > + setmetatable(router, router_mt) > + router.name = name > + M.routers[name] = router > + if name == STATIC_ROUTER_NAME then > + M.static_router = router > + export_static_router_attributes() > + end 9. This check can be removed if you move export_static_router_attributes call into legacy_cfg. 10. Looks like all your struggles in export_static_router_attributes() about error on non-configured router makes no sense since until cfg is called, vshard.router has no any methods except cfg and new. > + router_cfg(router, cfg, CFG_NEW) > + updage_lua_gc_state() > + return router > +end > +
next prev parent reply other threads:[~2018-08-01 18:43 UTC|newest] Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-07-31 16:25 [tarantool-patches] [PATCH 0/3] multiple routers AKhatskevich 2018-07-31 16:25 ` [tarantool-patches] [PATCH 1/3] Update only vshard part of a cfg on reload AKhatskevich 2018-08-01 18:43 ` [tarantool-patches] " Vladislav Shpilevoy 2018-08-03 20:03 ` Alex Khatskevich 2018-08-06 17:03 ` Vladislav Shpilevoy 2018-08-07 13:19 ` Alex Khatskevich 2018-08-08 11:17 ` Vladislav Shpilevoy 2018-07-31 16:25 ` [tarantool-patches] [PATCH 2/3] Move lua gc to a dedicated module AKhatskevich 2018-08-01 18:43 ` [tarantool-patches] " Vladislav Shpilevoy 2018-08-03 20:04 ` Alex Khatskevich 2018-08-06 17:03 ` Vladislav Shpilevoy 2018-08-08 11:17 ` Vladislav Shpilevoy 2018-07-31 16:25 ` [tarantool-patches] [PATCH 3/3] Introduce multiple routers feature AKhatskevich 2018-08-01 18:43 ` Vladislav Shpilevoy [this message] 2018-08-03 20:05 ` [tarantool-patches] " Alex Khatskevich 2018-08-06 17:03 ` Vladislav Shpilevoy 2018-08-07 13:18 ` Alex Khatskevich 2018-08-08 12:28 ` Vladislav Shpilevoy 2018-08-08 14:04 ` Alex Khatskevich 2018-08-08 15:37 ` Vladislav Shpilevoy 2018-08-01 14:30 ` [tarantool-patches] [PATCH] Check self arg passed for router objects AKhatskevich 2018-08-03 20:07 ` [tarantool-patches] [PATCH] Refactor config templates AKhatskevich 2018-08-06 15:49 ` [tarantool-patches] " 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=30ab88fc-fba0-11d8-254c-385e59caead7@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=avkhatskevich@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH 3/3] Introduce multiple routers feature' \ /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