From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id BDEDB46970F for ; Tue, 26 Nov 2019 16:13:46 +0300 (MSK) From: Leonid Date: Tue, 26 Nov 2019 16:13:43 +0300 Message-Id: <156ce93b495648d6f3fd6c879b0d9aaf56754a1e.1574773773.git.lvasiliev@tarantool.org> Subject: [Tarantool-patches] [PATCH] Move txn from shema to a separate module (use C API instead of FFI) List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: alexander.turenko@tarantool.org Cc: tarantool-patches@dev.tarantool.org 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 ``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 + * 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 + +#include +#include +#include + +#include + +#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 ``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 + * 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 +#include #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