Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: vdavydov.dev@gmail.com
Subject: [PATCH v3 1/2] session: store vtab both in struct and registry
Date: Fri, 21 Dec 2018 19:48:40 +0300	[thread overview]
Message-ID: <a68772d7bb2d1c9b9e38062c07f684dda64f5514.1545410736.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1545410736.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1545410736.git.v.shpilevoy@tarantool.org>

Before the patch vtabs were stored in a global array
only, called registry and accessed by session.type to
call a virtual method. But it does not allow to change
session vtab without affecting session type. This
feature is necessary to be able to outdate binary
sessions whose socket is closed.

Outdated, closed, sessions will return errors from all
its methods.

Needed for #3859
---
 src/box/applier.cc    |  5 ++++-
 src/box/lua/session.c |  3 ++-
 src/box/session.cc    | 10 +++++++++-
 src/box/session.h     | 12 +++++++++---
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/box/applier.cc b/src/box/applier.cc
index ff4af95e5..21d2e6bcb 100644
--- a/src/box/applier.cc
+++ b/src/box/applier.cc
@@ -587,7 +587,10 @@ applier_f(va_list ap)
 	 * Set correct session type for use in on_replace()
 	 * triggers.
 	 */
-	current_session()->type = SESSION_TYPE_APPLIER;
+	struct session *session = session_create_on_demand();
+	if (session == NULL)
+		return -1;
+	session_set_type(session, SESSION_TYPE_APPLIER);
 
 	/* Re-connect loop */
 	while (!fiber_is_cancelled()) {
diff --git a/src/box/lua/session.c b/src/box/lua/session.c
index d3d27643f..a4ddb201c 100644
--- a/src/box/lua/session.c
+++ b/src/box/lua/session.c
@@ -57,7 +57,8 @@ lbox_session_create(struct lua_State *L)
 		session->meta.fd = luaL_optinteger(L, 1, -1);
 	}
 	/* If a session already exists, simply reset its type */
-	session->type = STR2ENUM(session_type, luaL_optstring(L, 2, "console"));
+	session_set_type(session, STR2ENUM(session_type,
+					   luaL_optstring(L, 2, "console")));
 
 	lua_pushnumber(L, session->id);
 	return 1;
diff --git a/src/box/session.cc b/src/box/session.cc
index 64714cdcf..0ec118bca 100644
--- a/src/box/session.cc
+++ b/src/box/session.cc
@@ -92,6 +92,14 @@ session_on_stop(struct trigger *trigger, void * /* event */)
 	session_destroy(fiber_get_session(fiber()));
 }
 
+void
+session_set_type(struct session *session, enum session_type type)
+{
+	assert(type < session_type_MAX);
+	session->type = type;
+	session->vtab = &session_vtab_registry[type];
+}
+
 struct session *
 session_create(enum session_type type)
 {
@@ -105,7 +113,7 @@ session_create(enum session_type type)
 
 	session->id = sid_max();
 	memset(&session->meta, 0, sizeof(session->meta));
-	session->type = type;
+	session_set_type(session, type);
 	session->sql_flags = default_flags;
 	session->sql_default_engine = SQL_STORAGE_ENGINE_MEMTX;
 
diff --git a/src/box/session.h b/src/box/session.h
index df1dcbc62..d86939e48 100644
--- a/src/box/session.h
+++ b/src/box/session.h
@@ -97,6 +97,8 @@ struct session {
 	/** SQL Connection flag for current user session */
 	uint32_t sql_flags;
 	enum session_type type;
+	/** Session virtual methods. */
+	const struct session_vtab *vtab;
 	/** Session metadata. */
 	union session_meta meta;
 	/** Session user id and global grants */
@@ -140,6 +142,10 @@ struct session_vtab {
 
 extern struct session_vtab session_vtab_registry[];
 
+/** Change session type and vtab. */
+void
+session_set_type(struct session *session, enum session_type type);
+
 /**
  * Find a session by id.
  */
@@ -302,19 +308,19 @@ access_check_universe(user_access_t access);
 static inline int
 session_push(struct session *session, uint64_t sync, struct port *port)
 {
-	return session_vtab_registry[session->type].push(session, sync, port);
+	return session->vtab->push(session, sync, port);
 }
 
 static inline int
 session_fd(struct session *session)
 {
-	return session_vtab_registry[session->type].fd(session);
+	return session->vtab->fd(session);
 }
 
 static inline int
 session_sync(struct session *session)
 {
-	return session_vtab_registry[session->type].sync(session);
+	return session->vtab->sync(session);
 }
 
 /**
-- 
2.17.2 (Apple Git-113)

  reply	other threads:[~2018-12-21 16:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-21 16:48 [PATCH v3 0/2] Outdate binary session on disconnect Vladislav Shpilevoy
2018-12-21 16:48 ` Vladislav Shpilevoy [this message]
2018-12-21 16:48 ` [PATCH v3 2/2] session: outdate a session of a closed connection Vladislav Shpilevoy
2018-12-24 10:07 ` [PATCH v3 0/2] Outdate binary session on disconnect Vladimir Davydov

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=a68772d7bb2d1c9b9e38062c07f684dda64f5514.1545410736.git.v.shpilevoy@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [PATCH v3 1/2] session: store vtab both in struct and registry' \
    /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