From 490a73edb676f624d93d13490d029e37b46cc9fc Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Fri, 24 Apr 2015 15:36:54 +0300 Subject: [PATCH] gh-812: session.sync() Provide access to iproto sync via session.sync() binding. The value is valid only at start of a Lua call before the first yield, after which it may be replaced with a sync from another request running on the same session. --- src/box/iproto.cc | 1 + src/box/lua/session.cc | 13 +++++++++++++ src/box/session.cc | 1 + src/box/session.h | 18 ++++++++++++++++-- test/box/session.result | 8 ++++++++ test/box/session.test.lua | 2 ++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 809e534db6..a5db59fd98 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -653,6 +653,7 @@ iproto_process(struct iproto_request *ireq) if (unlikely(! evio_is_active(&con->output))) return; + ireq->session->sync = ireq->header.sync; struct obuf_svp svp = obuf_create_svp(out); try { switch (ireq->header.type) { diff --git a/src/box/lua/session.cc b/src/box/lua/session.cc index 8571df7129..991f2205b5 100644 --- a/src/box/lua/session.cc +++ b/src/box/lua/session.cc @@ -60,6 +60,18 @@ lbox_session_id(struct lua_State *L) return 1; } +/** + * Return the id of currently executed request. + * Many requests share the same session so this is only + * valid at session start. 0 for non-iproto sessions. + */ +static int +lbox_session_sync(struct lua_State *L) +{ + lua_pushnumber(L, current_session()->sync); + return 1; +} + /** * Session user id. * Note: effective user id (current_user()->uid) @@ -249,6 +261,7 @@ box_lua_session_init(struct lua_State *L) { static const struct luaL_reg sessionlib[] = { {"id", lbox_session_id}, + {"sync", lbox_session_sync}, {"uid", lbox_session_uid}, {"user", lbox_session_user}, {"su", lbox_session_su}, diff --git a/src/box/session.cc b/src/box/session.cc index 840ef3a0f0..e694f7c854 100644 --- a/src/box/session.cc +++ b/src/box/session.cc @@ -76,6 +76,7 @@ session_create(int fd, uint64_t cookie) session->id = sid_max(); session->fd = fd; session->cookie = cookie; + session->sync = 0; /* For on_connect triggers. */ credentials_init(&session->credentials, guest_user); if (fd >= 0) diff --git a/src/box/session.h b/src/box/session.h index e1720f51b6..09a9ea34a5 100644 --- a/src/box/session.h +++ b/src/box/session.h @@ -48,10 +48,24 @@ enum { SESSION_SEED_SIZE = 32, SESSION_DELIM_SIZE = 16 }; struct session { /** Session id. */ uint32_t id; - /** File descriptor - socket of the connected peer. */ + /** File descriptor - socket of the connected peer. + * Only if the session has a peer. + */ int fd; - /** Peer cookie - description of the peer. */ + /** + * Peer cookie - description of the peer. + * Only if the session has a peer. + */ uint64_t cookie; + /** + * For iproto requests, we set this field + * to the value of packet sync. Since the + * session may be reused between many requests, + * the value is true only at the beginning + * of the request, and gets distorted after + * the first yield. + */ + uint64_t sync; /** Authentication salt. */ char salt[SESSION_SEED_SIZE]; /** Cached user id and global grants */ diff --git a/test/box/session.result b/test/box/session.result index 1d254e10f7..dead886005 100644 --- a/test/box/session.result +++ b/test/box/session.result @@ -193,6 +193,10 @@ a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1] --- - true ... +a:eval('return session.sync() ~= 0') +--- +- true +... a:close() --- ... @@ -218,6 +222,10 @@ session.user() --- - admin ... +session.sync() +--- +- 0 +... fiber = nil --- ... diff --git a/test/box/session.test.lua b/test/box/session.test.lua index 3474dbb34c..56e5a0c350 100644 --- a/test/box/session.test.lua +++ b/test/box/session.test.lua @@ -75,6 +75,7 @@ session.on_disconnect(audit_disconnect) box.schema.user.grant('guest', 'read,write,execute', 'universe') a = net.box:new(LISTEN.host, LISTEN.service) a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1] +a:eval('return session.sync() ~= 0') a:close() -- cleanup @@ -86,6 +87,7 @@ space:drop() session.uid() session.user() +session.sync() fiber = nil session = nil box.schema.user.revoke('guest', 'read,write,execute', 'universe') -- GitLab