diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua index 2040d5e41e3cd69ef3d1740183c61d98ab321d5f..2bf772aa8c93fdc130913f4410e74556e8808394 100644 --- a/src/box/lua/net_box.lua +++ b/src/box/lua/net_box.lua @@ -422,21 +422,12 @@ 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 and not callback('reconnect_timeout') then - set_state('error', E_NO_CONNECTION) - return - end fiber.create(function() - local ok, err + local ok, err, timeout 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 + goto do_connect end ::handle_connection:: ok, err = pcall(protocol_sm) @@ -447,23 +438,30 @@ local function create_transport(host, port, user, password, callback, connection:close() connection = nil end + timeout = callback('reconnect_timeout') ::do_reconnect:: - local timeout = callback('reconnect_timeout') - while timeout and state == 'error_reconnect' do - fiber.sleep(timeout) - timeout = callback('reconnect_timeout') - if not timeout or state ~= 'error_reconnect' then - break - end - connection, greeting = - establish_connection(host, port, - callback('fetch_connect_timeout')) - if connection then - goto handle_connection - end - set_state('error_reconnect', E_NO_CONNECTION, greeting) - timeout = callback('reconnect_timeout') + if not timeout or state ~= 'error_reconnect' then + goto stop + end + fiber.sleep(timeout) + timeout = callback('reconnect_timeout') + if not timeout or state ~= 'error_reconnect' then + goto stop end + ::do_connect:: + connection, greeting = + establish_connection(host, port, callback('fetch_connect_timeout')) + if connection then + goto handle_connection + end + timeout = callback('reconnect_timeout') + if not timeout then + set_state('error', E_NO_CONNECTION, greeting) + goto stop + end + set_state('error_reconnect', E_NO_CONNECTION, greeting) + goto do_reconnect + ::stop:: send_buf:recycle() recv_buf:recycle() worker_fiber = nil @@ -993,15 +991,7 @@ end -- @retval Net.box object. -- local function connect(...) - local host, port, opts = parse_connect_params(...) - local connection, greeting = - establish_connection(host, port, opts.connect_timeout) - if not connection then - local dummy_conn = new_sm(host, port, opts) - dummy_conn.error = greeting - return dummy_conn - end - return new_sm(host, port, opts, connection, greeting) + return new_sm(parse_connect_params(...)) end local function check_remote_arg(remote, method) diff --git a/test/box/net.box.result b/test/box/net.box.result index faae5e9a5e39bda5bd1725df82c85ed204f24900..b6b6d88a4718d7a3e6d791408e2e2af19bc2b9be 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -3405,6 +3405,23 @@ ok, err - false - Connection closed ... +-- +-- gh-3856: wait_connected = false is ignored. +-- +c = net.connect('8.8.8.8:123456', {wait_connected = false}) +--- +... +c +--- +- opts: + wait_connected: false + host: 8.8.8.8 + state: initial + port: '123456' +... +c:close() +--- +... box.schema.func.drop('do_long') --- ... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua index dd6c2fd9440f7ebeae6c17b1c2c2171a536de12d..5152e3569428d00a269a7eb237ac329abf343950 100644 --- a/test/box/net.box.test.lua +++ b/test/box/net.box.test.lua @@ -1374,6 +1374,13 @@ ready = true while not err do fiber.sleep(0.01) end ok, err +-- +-- gh-3856: wait_connected = false is ignored. +-- +c = net.connect('8.8.8.8:123456', {wait_connected = false}) +c +c:close() + box.schema.func.drop('do_long') box.schema.user.revoke('guest', 'write', 'space', '_schema') box.schema.user.revoke('guest', 'read,write', 'space', '_space')