[Tarantool-patches] [PATCH] Move txn from shema to a separate module (use C API instead of FFI)

Leonid lvasiliev at tarantool.org
Tue Nov 26 16:13:43 MSK 2019


https://github.com/tarantool/tarantool/issues/4427
https://github.com/tarantool/tarantool/tree/lvasiliev/gh-4427-move-some-stuff-from-ffi-to-c-api

---
 src/box/CMakeLists.txt       |   2 +
 src/box/lua/init.c           |   4 +
 src/box/lua/schema.lua       |  71 -----------------
 src/box/lua/txn.c            | 145 +++++++++++++++++++++++++++++++++++
 src/box/lua/txn.h            |  49 ++++++++++++
 src/box/lua/txn.lua          |  53 +++++++++++++
 src/box/txn.c                |   2 +
 test/box/misc.result         |   1 +
 test/engine/savepoint.result |  12 +--
 9 files changed, 262 insertions(+), 77 deletions(-)
 create mode 100644 src/box/lua/txn.c
 create mode 100644 src/box/lua/txn.h
 create mode 100644 src/box/lua/txn.lua

diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index 5cd5cba81..71d691542 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -15,6 +15,7 @@ lua_source(lua_sources lua/serpent.lua)
 lua_source(lua_sources lua/xlog.lua)
 lua_source(lua_sources lua/key_def.lua)
 lua_source(lua_sources lua/merger.lua)
+lua_source(lua_sources lua/txn.lua)
 set(bin_sources)
 bin_source(bin_sources bootstrap.snap bootstrap.h)
 
@@ -143,6 +144,7 @@ add_library(box STATIC
     lua/info.c
     lua/stat.c
     lua/ctl.c
+    lua/txn.c
     lua/error.cc
     lua/session.c
     lua/net_box.c
diff --git a/src/box/lua/init.c b/src/box/lua/init.c
index 7ffed409d..0d0b0e0b9 100644
--- a/src/box/lua/init.c
+++ b/src/box/lua/init.c
@@ -53,6 +53,7 @@
 #include "box/lua/stat.h"
 #include "box/lua/info.h"
 #include "box/lua/ctl.h"
+#include "box/lua/txn.h"
 #include "box/lua/session.h"
 #include "box/lua/net_box.h"
 #include "box/lua/cfg.h"
@@ -67,6 +68,7 @@ extern char session_lua[],
 	tuple_lua[],
 	key_def_lua[],
 	schema_lua[],
+	txn_lua[],
 	load_cfg_lua[],
 	xlog_lua[],
 	feedback_daemon_lua[],
@@ -79,6 +81,7 @@ static const char *lua_sources[] = {
 	"box/session", session_lua,
 	"box/tuple", tuple_lua,
 	"box/schema", schema_lua,
+	"box/txn", txn_lua,
 	"box/feedback_daemon", feedback_daemon_lua,
 	"box/upgrade", upgrade_lua,
 	"box/net_box", net_box_lua,
@@ -312,6 +315,7 @@ box_lua_init(struct lua_State *L)
 	box_lua_info_init(L);
 	box_lua_stat_init(L);
 	box_lua_ctl_init(L);
+	box_lua_txn_init(L);
 	box_lua_session_init(L);
 	box_lua_xlog_init(L);
 	box_lua_execute_init(L);
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index e898c3aa6..d3c07b042 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -64,21 +64,6 @@ ffi.cdef[[
     box_index_count(uint32_t space_id, uint32_t index_id, int type,
                     const char *key, const char *key_end);
     /** \endcond public */
-    /** \cond public */
-    bool
-    box_txn();
-    int64_t
-    box_txn_id();
-    int
-    box_txn_begin();
-    /** \endcond public */
-    typedef struct txn_savepoint box_txn_savepoint_t;
-
-    box_txn_savepoint_t *
-    box_txn_savepoint();
-
-    int
-    box_txn_rollback_to_savepoint(box_txn_savepoint_t *savepoint);
 
     struct port_tuple_entry {
         struct port_tuple_entry *next;
@@ -123,7 +108,6 @@ ffi.cdef[[
         PRIV_REVOKE = 16384,
         PRIV_ALL  = 4294967295
     };
-
 ]]
 
 box.priv = {
@@ -318,61 +302,6 @@ local function update_param_table(table, defaults)
     return new_table
 end
 
-box.begin = function()
-    if builtin.box_txn_begin() == -1 then
-        box.error()
-    end
-end
-
-box.is_in_txn = builtin.box_txn
-
-box.savepoint = function()
-    local csavepoint = builtin.box_txn_savepoint()
-    if csavepoint == nil then
-        box.error()
-    end
-    return { csavepoint=csavepoint, txn_id=builtin.box_txn_id() }
-end
-
-local savepoint_type = ffi.typeof('box_txn_savepoint_t')
-
-local function check_savepoint(savepoint)
-    if savepoint == nil or savepoint.txn_id == nil or
-       savepoint.csavepoint == nil or
-       type(tonumber(savepoint.txn_id)) ~= 'number' or
-       type(savepoint.csavepoint) ~= 'cdata' or
-       not ffi.istype(savepoint_type, savepoint.csavepoint) then
-        error("Usage: box.rollback_to_savepoint(savepoint)")
-    end
-end
-
-box.rollback_to_savepoint = function(savepoint)
-    check_savepoint(savepoint)
-    if savepoint.txn_id ~= builtin.box_txn_id() then
-        box.error(box.error.NO_SUCH_SAVEPOINT)
-    end
-    if builtin.box_txn_rollback_to_savepoint(savepoint.csavepoint) == -1 then
-        box.error()
-    end
-end
-
-local function atomic_tail(status, ...)
-    if not status then
-        box.rollback()
-        error((...), 2)
-     end
-     box.commit()
-     return ...
-end
-
-box.atomic = function(fun, ...)
-    box.begin()
-    return atomic_tail(pcall(fun, ...))
-end
-
--- box.commit yields, so it's defined as Lua/C binding
--- box.rollback yields as well
-
 function update_format(format)
     local result = {}
     for i, given in ipairs(format) do
diff --git a/src/box/lua/txn.c b/src/box/lua/txn.c
new file mode 100644
index 000000000..1d07ff41e
--- /dev/null
+++ b/src/box/lua/txn.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#include <tarantool_ev.h>
+
+#include "box/box.h"
+#include "box/schema.h"
+#include "box/txn.h"
+
+#include "box/lua/txn.h"
+
+#include "lua/utils.h"
+#include "lua/trigger.h"
+
+
+static uint32_t CTID_STRUCT_TXN_SAVEPOINT_REF = 0;
+
+
+static int
+lbox_txn_begin(struct lua_State *L)
+{
+	int res = box_txn_begin();
+	if (res == -1)
+		return luaT_push_nil_and_error(L);
+
+	lua_pushnumber(L, 0);
+	return 1;
+}
+
+static int
+lbox_txn_is_in_txn(struct lua_State *L)
+{
+	bool res = box_txn();
+	lua_pushboolean(L, res);
+	return 1;
+}
+
+static int
+lbox_txn_id(struct lua_State *L)
+{
+	int64_t res = box_txn_id();
+
+	if (res == -1)
+		return luaT_push_nil_and_error(L);
+
+	lua_pushnumber(L, res);
+	return 1;
+}
+
+struct txn_savepoint*
+luaT_check_txn_savepoint(struct lua_State *L, int idx)
+{
+	if (lua_type(L, idx) != LUA_TCDATA)
+		return NULL;
+
+	uint32_t cdata_type;
+	struct txn_savepoint **sp_ptr = luaL_checkcdata(L, idx, &cdata_type);
+
+	if (sp_ptr == NULL || cdata_type != CTID_STRUCT_TXN_SAVEPOINT_REF)
+		return NULL;
+
+	return *sp_ptr;
+}
+
+static int 
+lbox_txn_rollback_to_savepoint(struct lua_State *L)
+{
+	struct txn_savepoint *sp;
+	if (lua_gettop(L) != 1
+	    || (sp = luaT_check_txn_savepoint(L, 1)) == NULL) {
+		 luaL_error(L, "Usage: txn:rollback to savepoint(savepoint)");
+	}
+
+	int rc = box_txn_rollback_to_savepoint(sp);
+	if (rc != 0)
+		return luaT_push_nil_and_error(L);
+
+	lua_pushnumber(L, 0);
+	return 1;
+}
+
+static int
+lbox_txn_savepoint(struct lua_State *L)
+{
+	struct txn_savepoint *sp = box_txn_savepoint();
+	if (sp == NULL)
+		return luaT_push_nil_and_error(L);
+
+	lua_pushlightuserdata(L, sp);
+	*(struct txn_savepoint **)luaL_pushcdata(L, CTID_STRUCT_TXN_SAVEPOINT_REF) = sp;
+	return 1;
+}
+
+static const struct luaL_Reg lbox_txn_lib[] = {
+	{ "begin",			lbox_txn_begin			},
+	{ "is_in_txn",			lbox_txn_is_in_txn		},
+	{ "txn_id",			lbox_txn_id			},
+	{ "savepoint",			lbox_txn_savepoint		},
+	{ "rollback_to_savepoint",	lbox_txn_rollback_to_savepoint	},
+	{ NULL,				NULL				}
+};
+
+void
+box_lua_txn_init(struct lua_State *L)
+{
+	luaL_cdef(L, "struct txn_savepoint;");
+	CTID_STRUCT_TXN_SAVEPOINT_REF = luaL_ctypeid(L, "struct txn_savepoint&");
+
+	luaL_register_module(L, "box.txn", lbox_txn_lib);
+	lua_pop(L, 1);
+}
diff --git a/src/box/lua/txn.h b/src/box/lua/txn.h
new file mode 100644
index 000000000..d9b643961
--- /dev/null
+++ b/src/box/lua/txn.h
@@ -0,0 +1,49 @@
+#ifndef INCLUDES_TARANTOOL_LUA_TXN_H
+#define INCLUDES_TARANTOOL_LUA_TXN_H
+
+/*
+ * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+struct lua_State;
+
+void
+box_lua_txn_init(struct lua_State *L);
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* INCLUDES_TARANTOOL_LUA_TXN_H */
+
diff --git a/src/box/lua/txn.lua b/src/box/lua/txn.lua
new file mode 100644
index 000000000..15e5290d8
--- /dev/null
+++ b/src/box/lua/txn.lua
@@ -0,0 +1,53 @@
+-- txn.lua (internal file)
+-- luacheck: ignore box
+
+box.begin = function()
+    local res, err = box.txn.begin()
+    if res == nil then
+        error(err)
+    end
+end
+
+box.is_in_txn = function()
+    return box.txn.is_in_txn()
+end
+
+box.savepoint = function()
+    local res, err = box.txn.savepoint()
+    if res == nil then
+        error(err)
+    end
+    return { csavepoint = res, txn_id = box.txn.txn_id() }
+end
+
+box.rollback_to_savepoint = function(savepoint)
+    if savepoint == nil then
+        error("Usage: txn:rollback to savepoint(savepoint)")
+    end
+
+    if savepoint.txn_id ~= box.txn.txn_id() then
+        box.error(box.error.NO_SUCH_SAVEPOINT)
+    end
+
+    local res, err = box.txn.rollback_to_savepoint(savepoint.csavepoint)
+    if res == nil then
+            error(err)
+    end
+end
+
+local function atomic_tail(status, ...)
+    if not status then
+        box.rollback()
+        error((...), 2)
+     end
+     box.commit()
+     return ...
+end
+
+box.atomic = function(fun, ...)
+    box.begin()
+    return atomic_tail(pcall(fun, ...))
+end
+
+-- box.commit yields, so it's defined as Lua/C binding
+-- box.rollback yields as well
diff --git a/src/box/txn.c b/src/box/txn.c
index 963ec8eeb..54a0436ad 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -33,6 +33,7 @@
 #include "tuple.h"
 #include "journal.h"
 #include <fiber.h>
+#include <lauxlib.h>
 #include "xrow.h"
 
 double too_long_threshold;
@@ -877,3 +878,4 @@ txn_on_yield(struct trigger *trigger, void *event)
 	txn_set_flag(txn, TXN_IS_ABORTED_BY_YIELD);
 	return 0;
 }
+
diff --git a/test/box/misc.result b/test/box/misc.result
index d2a20307a..3eb27fbdc 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -86,6 +86,7 @@ t
   - space
   - stat
   - tuple
+  - txn
 ...
 t = nil
 ---
diff --git a/test/engine/savepoint.result b/test/engine/savepoint.result
index 86a2d0be2..501ba80c2 100644
--- a/test/engine/savepoint.result
+++ b/test/engine/savepoint.result
@@ -18,7 +18,7 @@ s1 = box.savepoint()
 ...
 box.rollback_to_savepoint(s1)
 ---
-- error: 'builtin/box/schema.lua: Usage: box.rollback_to_savepoint(savepoint)'
+- error: 'builtin/box/txn.lua: Usage: txn:rollback to savepoint(savepoint)'
 ...
 box.begin() s1 = box.savepoint()
 ---
@@ -327,27 +327,27 @@ test_run:cmd("setopt delimiter ''");
 ok1, errmsg1
 ---
 - false
-- 'builtin/box/schema.lua: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/txn.lua: Usage: txn:rollback to savepoint(savepoint)'
 ...
 ok2, errmsg2
 ---
 - false
-- 'builtin/box/schema.lua: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/txn.lua: Usage: txn:rollback to savepoint(savepoint)'
 ...
 ok3, errmsg3
 ---
 - false
-- 'builtin/box/schema.lua: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/txn.lua: Usage: txn:rollback to savepoint(savepoint)'
 ...
 ok4, errmsg4
 ---
 - false
-- 'builtin/box/schema.lua: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/txn.lua: Usage: txn:rollback to savepoint(savepoint)'
 ...
 ok5, errmsg5
 ---
 - false
-- 'builtin/box/schema.lua: Usage: box.rollback_to_savepoint(savepoint)'
+- 'Can not rollback to savepoint: the savepoint does not exist'
 ...
 s:select{}
 ---
-- 
2.17.1



More information about the Tarantool-patches mailing list