From f278d3f0f38f4b62d23561dced36fefb97146309 Mon Sep 17 00:00:00 2001 From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Date: Fri, 30 Mar 2018 14:33:01 +0300 Subject: [PATCH] netbox: fix a bug with ignored reconnect_after If a remote host is unreachable on the first connection attempt, and reconnect_after is set, then netbox state machine enters error state, but it must enter error_reconnect. Do it. The bug was introduced by me in d2468dacaf6119574d705c08df6e23892b52db08. --- src/box/lua/net_box.lua | 14 ++++++++++++-- test/box/net.box.result | 13 +++++++++++++ test/box/net.box.test.lua | 9 +++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua index f0ea38d399..8df70e578e 100644 --- a/src/box/lua/net_box.lua +++ b/src/box/lua/net_box.lua @@ -219,15 +219,24 @@ local function create_transport(host, port, user, password, callback, local function start() if state ~= 'initial' then return not is_final_state[state] end - if not connection then + if not connection and not callback('reconnect_timeout') then set_state('error', E_NO_CONNECTION) return end fiber.create(function() + local ok, err worker_fiber = fiber_self() fiber.name(string.format('%s:%s (net.box)', host, port), {truncate=true}) + -- It is possible, if the first connection attempt had + -- been failed, but reconnect timeout is set. In such + -- a case the worker must be run, and immediately + -- start reconnecting. + if not connection then + set_state('error_reconnect', E_NO_CONNECTION, greeting) + goto do_reconnect + end ::handle_connection:: - local ok, err = pcall(protocol_sm) + ok, err = pcall(protocol_sm) if not (ok or is_final_state[state]) then set_state('error', E_UNKNOWN, err) end @@ -235,6 +244,7 @@ local function create_transport(host, port, user, password, callback, connection:close() connection = nil end + ::do_reconnect:: local timeout = callback('reconnect_timeout') while timeout and state == 'error_reconnect' do fiber.sleep(timeout) diff --git a/test/box/net.box.result b/test/box/net.box.result index 78178ab9ef..cf7b27f0bb 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -2383,6 +2383,19 @@ s:drop() c:close() --- ... +-- +-- Test a case, when netbox can not connect first time, but +-- reconnect_after is set. +-- +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) +--- +... +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end +--- +... +c:close() +--- +... box.schema.user.revoke('guest', 'read,write,execute', 'universe') --- ... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua index 47948ac958..576b5cfeab 100644 --- a/test/box/net.box.test.lua +++ b/test/box/net.box.test.lua @@ -972,6 +972,15 @@ c:ping() s:drop() c:close() + +-- +-- Test a case, when netbox can not connect first time, but +-- reconnect_after is set. +-- +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end +c:close() + box.schema.user.revoke('guest', 'read,write,execute', 'universe') c.state c = nil -- GitLab