From 4cc9972d319cac9806dd8d139dce6aa4c12b16dd Mon Sep 17 00:00:00 2001 From: bigbes <bigbes@gmail.com> Date: Wed, 10 Dec 2014 04:54:56 +0300 Subject: [PATCH] Fixes gh-636 - Flush schema in box.net.box Added method remote:reload_schema() --- src/lua/box_net_box.lua | 36 +++++++-------- test/box/box.net.box.result | 82 ++++++++++++++++++++++++++++++++++- test/box/box.net.box.test.lua | 25 +++++++++++ 3 files changed, 125 insertions(+), 18 deletions(-) diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua index aa293dee61..91b6f483b0 100644 --- a/src/lua/box_net_box.lua +++ b/src/lua/box_net_box.lua @@ -40,20 +40,18 @@ local GREETING_SIZE = 128 local TIMEOUT_INFINITY = 500 * 365 * 86400 -local sequence_mt = { __serialize = 'sequence'} -local mapping_mt = { __serialize = 'mapping'} +local sequence_mt = { __serialize = 'sequence' } +local mapping_mt = { __serialize = 'mapping' } local CONSOLE_FAKESYNC = 15121974 local function request(header, body) - -- hint msgpack to always encode header and body as a map header = msgpack.encode(setmetatable(header, mapping_mt)) body = msgpack.encode(setmetatable(body, mapping_mt)) local len = msgpack.encode(string.len(header) + string.len(body)) - return len .. header .. body end @@ -158,8 +156,7 @@ local proto = { end, -- select - select = function(sync, spaceno, indexno, key, opts) - + select = function(sync, spaceno, indexno, key, opts) if opts == nil then opts = {} end @@ -517,6 +514,17 @@ local remote_methods = { } end, + reload_schema = function(self) + xpcall(function() self:_load_schema() end, + function(e) + log.info("Can't load schema: %s", tostring(e)) + end) + + if self.state ~= 'error' and self.state ~= 'closed' then + self:_switch_state('active') + end + end, + close = function(self) if self.state ~= 'closed' then self:_switch_state('closed') @@ -779,11 +787,11 @@ local remote_methods = { _auth = function(self) if self.opts.user == nil or self.opts.password == nil then - self:_switch_state 'authen' + self:_switch_state('authen') return end - self:_switch_state 'auth' + self:_switch_state('auth') local auth_res = self:_request_internal('auth', false, self.opts.user, self.opts.password, self.handshake) @@ -793,7 +801,7 @@ local remote_methods = { return end - self:_switch_state 'authen' + self:_switch_state('authen') end, -- states wakeup _read_worker @@ -821,10 +829,9 @@ local remote_methods = { return false end, - _load_schema = function(self) - if self.state ~= 'authen' then - self:_fatal 'Can not load schema from the state' + if self.state == 'closed' or self.state == 'error' then + self:_fatal('Can not load schema from the state') return end @@ -837,7 +844,6 @@ local remote_methods = { local sl = {} - for _, space in pairs(spaces) do local name = space[3] local id = space[1] @@ -851,7 +857,6 @@ local remote_methods = { field_count = field_count, enabled = true, index = {} - } if #space > 5 and string.match(space[6], 'temporary') then s.temporary = true @@ -863,7 +868,6 @@ local remote_methods = { sl[id] = s sl[name] = s - end for _, index in pairs(indexes) do @@ -1072,11 +1076,9 @@ local remote_methods = { end, _request_internal = function(self, name, raise, ...) - local sync = self.proto:sync() local request = self.proto[name](sync, ...) return self:_request_raw(sync, request, raise) - end, -- private (low level) methods diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result index b5af04d8a7..8a3590ecad 100644 --- a/test/box/box.net.box.result +++ b/test/box/box.net.box.result @@ -141,7 +141,7 @@ cn.space.net_box_test_space:insert{234, 1,2,3} ... cn.space.net_box_test_space.insert{234, 1,2,3} --- -- error: 'builtin/net.box.lua:229: Use space:method(...) instead space.method(...)' +- error: 'builtin/net.box.lua:226: Use space:method(...) instead space.method(...)' ... cn.space.net_box_test_space:replace{354, 1,2,3} --- @@ -648,3 +648,83 @@ end; gh594() --- ... +-- #636: Reload schema on demand +sp = box.schema.create_space('test_old') +--- +... +sp:create_index('primary') +--- +- unique: true + parts: + - type: NUM + fieldno: 1 + id: 0 + space_id: 512 + name: primary + type: TREE +... +sp:insert{1, 2, 3} +--- +- [1, 2, 3] +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +uri = string.format('%s:%s', LISTEN.host, LISTEN.service) +--- +... +con = remote.new(uri) +--- +... +con:ping() +--- +- true +... +con.space.test_old:select{} +--- +- - [1, 2, 3] +... +con.space.test:select{} +--- +- error: '[string "return con.space.test:select{} "]:1: attempt to index field ''test'' + (a nil value)' +... +sp = box.schema.create_space('test') +--- +... +sp:create_index('primary') +--- +- unique: true + parts: + - type: NUM + fieldno: 1 + id: 0 + space_id: 513 + name: primary + type: TREE +... +sp:insert{2, 3, 4} +--- +- [2, 3, 4] +... +con.space.test:select{} +--- +- error: '[string "return con.space.test:select{} "]:1: attempt to index field ''test'' + (a nil value)' +... +con:reload_schema() +--- +... +con.space.test:select{} +--- +- - [2, 3, 4] +... +box.space.test:drop() +--- +... +box.space.test_old:drop() +--- +... +con:close() +--- +... diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua index 65309c0321..76d529e97d 100644 --- a/test/box/box.net.box.test.lua +++ b/test/box/box.net.box.test.lua @@ -262,3 +262,28 @@ function gh594() end; --# setopt delimiter '' gh594() + +-- #636: Reload schema on demand +sp = box.schema.create_space('test_old') +sp:create_index('primary') +sp:insert{1, 2, 3} + +LISTEN = require('uri').parse(box.cfg.listen) +uri = string.format('%s:%s', LISTEN.host, LISTEN.service) + +con = remote.new(uri) +con:ping() +con.space.test_old:select{} +con.space.test:select{} + +sp = box.schema.create_space('test') +sp:create_index('primary') +sp:insert{2, 3, 4} + +con.space.test:select{} +con:reload_schema() +con.space.test:select{} + +box.space.test:drop() +box.space.test_old:drop() +con:close() -- GitLab