From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladislav Shpilevoy Subject: [PATCH 4/4] session: kill a session of a closed connection Date: Fri, 7 Dec 2018 18:46:35 +0300 Message-Id: <52080b13da7f20e84138d551f4c65f46d0781907.1544197465.git.v.shpilevoy@tarantool.org> In-Reply-To: References: In-Reply-To: References: To: tarantool-patches@freelists.org Cc: vdavydov.dev@gmail.com List-ID: Once a connection is closed, a long-running user request can not learn about this occasion. Even box.sesion.push() still works. This patch makes such disconnected session dead. So a user can determine if a connection is closed by looking at session type == 'dead', or checking for errors from box.session.push(). Closes #3859 --- src/box/iproto.cc | 9 +++++--- test/box/push.result | 50 ++++++++++++++++++++++++++++++++++++++++++ test/box/push.test.lua | 22 +++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 19ee67958..b6c2ab587 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1225,9 +1225,12 @@ tx_process_disconnect(struct cmsg *m) { struct iproto_connection *con = container_of(m, struct iproto_connection, disconnect_msg); - if (con->session != NULL && !rlist_empty(&session_on_disconnect)) { - tx_fiber_init(con->session, 0); - session_run_on_disconnect_triggers(con->session); + if (con->session != NULL) { + session_kill(con->session); + if (! rlist_empty(&session_on_disconnect)) { + tx_fiber_init(con->session, 0); + session_run_on_disconnect_triggers(con->session); + } } } diff --git a/test/box/push.result b/test/box/push.result index af730c1a7..d2f6a6803 100644 --- a/test/box/push.result +++ b/test/box/push.result @@ -497,6 +497,56 @@ box.schema.func.drop('do_pushes') s:drop() --- ... +-- +-- gh-3859: box.session.push() succeeds even after the connection +-- is closed. +-- +chan_push = fiber.channel() +--- +... +chan_disconnected = fiber.channel() +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function do_long_and_push() + box.session.on_disconnect(function() chan_disconnected:put(true) end) + chan_push:get() + ok, err = box.session.push(100) + chan_push:put(err) +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +box.schema.func.create('do_long_and_push') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'do_long_and_push') +--- +... +f = fiber.create(function() c:call('do_long_and_push') end) +--- +... c:close() --- ... +chan_disconnected:get() +--- +- true +... +chan_push:put(true) +--- +- true +... +chan_push:get() +--- +- Session 'dead' does not support push() +... +box.schema.func.drop('do_long_and_push') +--- +... diff --git a/test/box/push.test.lua b/test/box/push.test.lua index 893cf0153..514c08b3e 100644 --- a/test/box/push.test.lua +++ b/test/box/push.test.lua @@ -237,4 +237,26 @@ keys box.schema.func.drop('do_push_and_duplicate') box.schema.func.drop('do_pushes') s:drop() + +-- +-- gh-3859: box.session.push() succeeds even after the connection +-- is closed. +-- +chan_push = fiber.channel() +chan_disconnected = fiber.channel() +test_run:cmd("setopt delimiter ';'") +function do_long_and_push() + box.session.on_disconnect(function() chan_disconnected:put(true) end) + chan_push:get() + ok, err = box.session.push(100) + chan_push:put(err) +end; +test_run:cmd("setopt delimiter ''"); +box.schema.func.create('do_long_and_push') +box.schema.user.grant('guest', 'execute', 'function', 'do_long_and_push') +f = fiber.create(function() c:call('do_long_and_push') end) c:close() +chan_disconnected:get() +chan_push:put(true) +chan_push:get() +box.schema.func.drop('do_long_and_push') -- 2.17.2 (Apple Git-113)