[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