From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: vdavydov.dev@gmail.com Subject: [PATCH v2 4/4] session: outdate a session of a closed connection Date: Tue, 11 Dec 2018 19:10:23 +0300 [thread overview] Message-ID: <0bf15f316a62b1c78a0f4b8c17a0b33a741b142f.1544544183.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1544544183.git.v.shpilevoy@tarantool.org> In-Reply-To: <cover.1544544183.git.v.shpilevoy@tarantool.org> 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 'rotten'. So a user can determine if a connection is closed by looking at session.fd() == -1, or checking for errors from box.session.push(). Closes #3859 --- src/box/iproto.cc | 27 ++++++++++++++++++++--- test/box/push.result | 50 ++++++++++++++++++++++++++++++++++++++++++ test/box/push.test.lua | 22 +++++++++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/box/iproto.cc b/src/box/iproto.cc index e6eefc3d8..8fddc76ef 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1239,14 +1239,35 @@ tx_fiber_init(struct session *session, uint64_t sync) fiber_set_user(f, &session->credentials); } +static int +iproto_disconnected_session_push(struct session *session, uint64_t sync, + struct port *port) +{ + (void) session; + (void) sync; + (void) port; + diag_set(ClientError, ER_NO_CONNECTION); + return -1; +} + +static const struct session_vtab iproto_disconnected_session_vtab = { + /* .push = */ iproto_disconnected_session_push, + /* .fd = */ generic_session_fd, + /* .sync = */ generic_session_sync, +}; + static void 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_set_type(con->session, SESSION_TYPE_BINARY, + &iproto_disconnected_session_vtab); + 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..6f858f38a 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() +--- +- Connection is not established +... +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)
prev parent reply other threads:[~2018-12-11 16:10 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-12-11 16:10 [PATCH v2 0/4] Outdate binary session on disconnect Vladislav Shpilevoy 2018-12-11 16:10 ` [PATCH v2 1/4] console: forbid arbitrary session type setting Vladislav Shpilevoy 2018-12-21 11:17 ` Vladimir Davydov 2018-12-11 16:10 ` [PATCH v2 2/4] session: minimize number of session type resets Vladislav Shpilevoy 2018-12-11 16:10 ` [PATCH v2 3/4] session: store vtab in struct session Vladislav Shpilevoy 2018-12-21 11:04 ` Vladimir Davydov 2018-12-21 11:23 ` [tarantool-patches] " Vladislav Shpilevoy 2018-12-11 16:10 ` Vladislav Shpilevoy [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=0bf15f316a62b1c78a0f4b8c17a0b33a741b142f.1544544183.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [PATCH v2 4/4] session: outdate a session of a closed connection' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox