diff --git a/src/box/lua/box_net.lua b/src/box/lua/box_net.lua index 1bf1fb59848686742cdb08f76e72d49f5eed847d..2f86d071de5dc5fc165d379cd1379b9283881c40 100644 --- a/src/box/lua/box_net.lua +++ b/src/box/lua/box_net.lua @@ -282,6 +282,11 @@ box.net.box.new = function(host, port, reconnect_timeout) port = port, reconnect_timeout = reconnect_timeout, closed = false, + timedout = {}, + + title = function(self) + return sprintf('%s:%s', tostring(self.host), tostring(self.port)) + end, processing = { last_sync = 0, @@ -343,6 +348,7 @@ box.net.box.new = function(host, port, reconnect_timeout) -- timeout if res == nil then + self.timedout[ sync ] = true if op == box.net.box.PING then return false else @@ -371,7 +377,10 @@ box.net.box.new = function(host, port, reconnect_timeout) return totuples(body[box.net.box.DATA]) end else - error(res[2]) + if op == 65280 then + return false + end + errorf('%s: %s', self:title(), res[2]) end end, @@ -447,7 +456,13 @@ box.net.box.new = function(host, port, reconnect_timeout) if self.processing[sync] ~= nil then self.processing[sync]:put({true, code, resp:sub(offset)}, 0) else - print("Unexpected response ", sync) + if self.timedout[ sync ] then + self.timedout[ sync ] = nil + printf("Timed out response from %s", self:title()) + else + printf("Unexpected response %s from %s", + sync, self:title()) + end end end @@ -484,6 +499,7 @@ box.net.box.new = function(host, port, reconnect_timeout) ch:put({ false, message }, 0) end end + self.timedout = {} end, close = function(self) diff --git a/test/box/ipc.result b/test/box/ipc.result index f39009cd526e198bab420042babafa6cc0dd9d53..42fbcb4b3d44c4538b3ac528a2736345ab4cae1d 100644 --- a/test/box/ipc.result +++ b/test/box/ipc.result @@ -377,3 +377,69 @@ ch:is_closed() --- - true ... +-- race conditions +chs= {} +--- +... +count= 0 +--- +... +res= { } +--- +... +--# setopt delimiter ';' +for i = 1, 10 do table.insert(chs, box.ipc.channel()) end; +--- +... +for i = 1, 10 do + local no = i box.fiber.wrap( + function() + box.fiber.self():name('pusher') + while true do + chs[no]:put({no}) + box.fiber.sleep(0.001 * math.random()) + end + end + ) +end; +--- +... +for i = 1, 10 do + local no = i box.fiber.wrap( + function() + box.fiber.self():name('receiver') + while true do + local r = chs[no]:get(math.random() * .001) + if r ~= nil and r[1] == no then + res[no] = true + elseif r ~= nil then + break + end + box.fiber.sleep(0.001 * math.random()) + count = count + 1 + end + res[no] = false + end + ) +end; +--- +... +for i = 1, 100 do box.fiber.sleep(0.01) if count > 2000 then break end end; +--- +... +count > 2000, #res, res; +--- +- true +- 10 +- - true + - true + - true + - true + - true + - true + - true + - true + - true + - true +... +--# setopt delimiter '' diff --git a/test/box/ipc.test b/test/box/ipc.test deleted file mode 100644 index 074af0c3a3697c0d537e9560a0990bc6685a794e..0000000000000000000000000000000000000000 --- a/test/box/ipc.test +++ /dev/null @@ -1,62 +0,0 @@ -# encoding: tarantool -# -import sys - -exec admin "lua ch = box.ipc.channel()" -exec admin "lua ch:is_full()" -exec admin "lua ch:is_empty()" -exec admin "lua ch:get(.1)" -exec admin "lua ch:put()" -exec admin "lua ch:put('test')" -exec admin "lua ch:get()" -exec admin "lua ch:get('wrong timeout')" -exec admin "lua ch:get(-10)" -exec admin "lua ch:put(234)" -exec admin "lua ch:put(345, .5)" -exec admin "lua ch:is_full()" -exec admin "lua ch:is_empty()" -exec admin "lua buffer = {}" -exec admin "lua tfbr = box.fiber.create(function() box.fiber.detach() while true do table.insert(buffer, ch:get()) end end)" -exec admin "lua box.fiber.resume(tfbr)" -exec admin "lua for i = 1, 10 do print(i, ' ', ch:put(i, 0.1)) end" -exec admin "lua ch:has_readers()" -exec admin "lua ch:has_writers()" -exec admin "lua box.fiber.cancel(tfbr)" - -exec admin "lua ch:has_readers()" -exec admin "lua ch:has_writers()" -exec admin "lua ch:put(box.info.pid)" -exec admin "lua ch:is_full()" -exec admin "lua ch:is_empty()" -exec admin "lua ch:get(box.info.pid) == box.info.pid" -exec admin "lua for i, v in pairs(buffer) do print(v) end" - -exec admin "lua ch:is_empty()" -exec admin "lua ch:broadcast()" -exec admin "lua ch:broadcast(123)" -exec admin "lua ch:get()" - -exec admin "lua ch:is_full()" -exec admin "lua ch:is_empty()" -exec admin "lua tfbr = box.fiber.create(function() box.fiber.detach() while true do local v = ch:get() table.insert(buffer, 'tfbr - ' .. tostring(v)) end end)" -exec admin "lua box.fiber.resume(tfbr)" -exec admin "lua tfbr2 = box.fiber.create(function() box.fiber.detach() while true do local v = ch:get() table.insert(buffer, 'tfbr2 - ' .. tostring(v)) end end)" -exec admin "lua box.fiber.resume(tfbr2)" - -exec admin "lua buffer = {}" - -exec admin "lua for i, v in pairs(buffer) do print(v) end" -exec admin "lua ch:is_full()" -exec admin "lua ch:is_empty()" -exec admin "lua ch:put(1)" -exec admin "lua ch:put(2)" -exec admin "lua ch:put(3)" -exec admin "lua ch:put(4)" -exec admin "lua ch:put(5)" -exec admin "lua ch:broadcast('broadcast message!')" -exec admin "lua for i = 35, 45 do print(ch:put(i)) end" - - -exec admin "lua for i, v in pairs(buffer) do print(v) end" - - diff --git a/test/box/ipc.test.lua b/test/box/ipc.test.lua index a7ce76657977412d2746262af6ddc49f351991a8..e6b976067c238e6e1aac03b09787e0c44ac94e63 100644 --- a/test/box/ipc.test.lua +++ b/test/box/ipc.test.lua @@ -108,3 +108,50 @@ ch:get() ch:get() ch:put(10) ch:is_closed() + + + +-- race conditions +chs= {} +count= 0 +res= { } +--# setopt delimiter ';' +for i = 1, 10 do table.insert(chs, box.ipc.channel()) end; + + +for i = 1, 10 do + local no = i box.fiber.wrap( + function() + box.fiber.self():name('pusher') + while true do + chs[no]:put({no}) + box.fiber.sleep(0.001 * math.random()) + end + end + ) +end; + +for i = 1, 10 do + local no = i box.fiber.wrap( + function() + box.fiber.self():name('receiver') + while true do + local r = chs[no]:get(math.random() * .001) + if r ~= nil and r[1] == no then + res[no] = true + elseif r ~= nil then + break + end + box.fiber.sleep(0.001 * math.random()) + count = count + 1 + end + res[no] = false + end + ) +end; + +for i = 1, 100 do box.fiber.sleep(0.01) if count > 2000 then break end end; + +count > 2000, #res, res; + +--# setopt delimiter '' diff --git a/test/box/net.box.result b/test/box/net.box.result index 1870473c8020e8346bc91513f0d820c5545aadd8..3747572dbd6f593a317f6325a498c4f1287b5f10 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -374,11 +374,11 @@ remote:close() ... remote:close() --- -- error: '[string "-- box_net.lua (internal file)..."]:491: box.net.box: already closed' +- error: '[string "-- box_net.lua (internal file)..."]:507: box.net.box: already closed' ... remote:ping() --- -- error: '[string "-- box_net.lua (internal file)..."]:496: box.net.box: connection +- error: '[string "-- box_net.lua (internal file)..."]:512: box.net.box: connection was closed' ... space:drop()