diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 809e534db675951701e5bba40a1d8d22755c68ac..a5db59fd984024fc533b8383ab22a95932781b15 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 8571df71296bb92baa96f68902268a54c234808d..991f2205b5be8fd2ecb77693671194e6485cb7f7 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 840ef3a0f01f1549fac86aa7e4db4b4274c1d645..e694f7c8543bc0ca4b049de2c744f91b54b2896a 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 e1720f51b692c5462a86bc1a34f6a6ed6d49c248..09a9ea34a52ba27c76a1a2d44497830a192b59c2 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 1d254e10f7cbfd2c77c4eb609f504ad67007633e..dead886005596ab1d45d415b5849938099a761b8 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 3474dbb34c855ff435049962204afd4ffc242ff5..56e5a0c35016c45117d2066664115a646b18ef90 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')