[Tarantool-patches] [PATCH] net.box: add __serialize and __tostring methods for future objects
Vladimir Davydov
vdavydov at tarantool.org
Fri Aug 13 15:58:19 MSK 2021
Example output (for more examples see the test output):
tarantool> f = c:eval('return 123', {}, {is_async = true})
---
...
tarantool> tostring(f)
---
- 'net.box.request: 7'
...
tarantool> f
---
- method: eval
on_push_ctx: []
result: [123]
on_push: 'function: builtin#91'
sync: 7
...
Closes #6314
---
https://github.com/tarantool/tarantool/issues/6314
https://github.com/tarantool/tarantool/tree/vdavydov/netbox-future-serialize
src/box/lua/net_box.c | 68 +++++++++++++
test/box/net.box_fiber-async_gh-3107.result | 95 ++++++++++++++++++-
test/box/net.box_fiber-async_gh-3107.test.lua | 28 +++++-
3 files changed, 183 insertions(+), 8 deletions(-)
diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c
index 229dec590cf9..19ceec9544b6 100644
--- a/src/box/lua/net_box.c
+++ b/src/box/lua/net_box.c
@@ -82,6 +82,30 @@ enum netbox_method {
netbox_method_MAX
};
+static const char *netbox_method_str[] = {
+ [NETBOX_PING] = "ping",
+ [NETBOX_CALL_16] = "call_16",
+ [NETBOX_CALL_17] = "call",
+ [NETBOX_EVAL] = "eval",
+ [NETBOX_INSERT] = "insert",
+ [NETBOX_REPLACE] = "replace",
+ [NETBOX_DELETE] = "delete",
+ [NETBOX_UPDATE] = "update",
+ [NETBOX_UPSERT] = "upsert",
+ [NETBOX_SELECT] = "select",
+ [NETBOX_EXECUTE] = "execute",
+ [NETBOX_PREPARE] = "prepare",
+ [NETBOX_UNPREPARE] = "unprepare",
+ [NETBOX_GET] = "get",
+ [NETBOX_MIN] = "min",
+ [NETBOX_MAX] = "max",
+ [NETBOX_COUNT] = "count",
+ [NETBOX_BEGIN] = "begin",
+ [NETBOX_COMMIT] = "commit",
+ [NETBOX_ROLLBACK] = "rollback",
+ [NETBOX_INJECT] = "inject",
+};
+
struct netbox_registry {
/** Next request id. */
uint64_t next_sync;
@@ -1420,6 +1444,48 @@ luaT_netbox_request_gc(struct lua_State *L)
return 0;
}
+static int
+luaT_netbox_request_serialize(struct lua_State *L)
+{
+ struct netbox_request *request = luaT_check_netbox_request(L, 1);
+ lua_newtable(L);
+ luaL_pushuint64(L, request->sync);
+ lua_setfield(L, -2, "sync");
+ lua_pushstring(L, netbox_method_str[request->method]);
+ lua_setfield(L, -2, "method");
+ lua_rawgeti(L, LUA_REGISTRYINDEX, request->buffer_ref);
+ lua_setfield(L, -2, "buffer");
+ if (request->skip_header) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "skip_header");
+ }
+ lua_rawgeti(L, LUA_REGISTRYINDEX, request->on_push_ref);
+ lua_setfield(L, -2, "on_push");
+ lua_rawgeti(L, LUA_REGISTRYINDEX, request->on_push_ctx_ref);
+ lua_setfield(L, -2, "on_push_ctx");
+ if (request->result_ref != LUA_NOREF) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, request->result_ref);
+ lua_setfield(L, -2, "result");
+ }
+ if (request->error != NULL) {
+ diag_set_error(diag_get(), request->error);
+ luaT_pusherror(L, request->error);
+ lua_setfield(L, -2, "error");
+ }
+ return 1;
+}
+
+static int
+luaT_netbox_request_tostring(struct lua_State *L)
+{
+ char buf[32];
+ struct netbox_request *request = luaT_check_netbox_request(L, 1);
+ snprintf(buf, sizeof(buf), "%s: %llu", netbox_request_typename,
+ (unsigned long long)request->sync);
+ lua_pushstring(L, buf);
+ return 1;
+}
+
/**
* Returns true if the response was received for the given request.
*/
@@ -2052,6 +2118,8 @@ luaopen_net_box(struct lua_State *L)
static const struct luaL_Reg netbox_request_meta[] = {
{ "__gc", luaT_netbox_request_gc },
+ {"__serialize", luaT_netbox_request_serialize },
+ {"__tostring", luaT_netbox_request_tostring },
{ "is_ready", luaT_netbox_request_is_ready },
{ "result", luaT_netbox_request_result },
{ "wait_result", luaT_netbox_request_wait_result },
diff --git a/test/box/net.box_fiber-async_gh-3107.result b/test/box/net.box_fiber-async_gh-3107.result
index aaaca351a579..f2fbbde3d1bd 100644
--- a/test/box/net.box_fiber-async_gh-3107.result
+++ b/test/box/net.box_fiber-async_gh-3107.result
@@ -1,3 +1,6 @@
+test_run = require('test_run').new()
+---
+...
fiber = require 'fiber'
---
...
@@ -10,10 +13,7 @@ net = require('net.box')
cond = nil
---
...
-box.schema.func.create('long_function')
----
-...
-box.schema.user.grant('guest', 'execute', 'function', 'long_function')
+box.schema.user.grant('guest', 'execute', 'universe')
---
...
function long_function(...) cond = fiber.cond() cond:wait() return ... end
@@ -104,7 +104,92 @@ err:find('Usage') ~= nil
---
- true
...
-box.schema.func.drop('long_function')
+--
+-- __serialize and __tostring future methods
+--
+future = c:call('long_function', {1, 2, 3}, {is_async = true})
+---
+...
+tostring(future)
+---
+- 'net.box.request: 5'
+...
+future
+---
+- on_push_ctx: []
+ method: call
+ sync: 5
+ on_push: 'function: builtin#91'
+...
+finalize_long()
+---
+...
+future:wait_result()
+---
+- [1, 2, 3]
+...
+future
+---
+- method: call
+ on_push_ctx: []
+ result: [1, 2, 3]
+ on_push: 'function: builtin#91'
+ sync: 5
+...
+future = c:eval('assert(false)', {}, {is_async = true})
+---
+...
+tostring(future)
+---
+- 'net.box.request: 6'
+...
+future:wait_result()
+---
+- null
+- 'eval:1: assertion failed!'
+...
+future
+---
+- error: 'eval:1: assertion failed!'
+ method: eval
+ on_push_ctx: []
+ on_push: 'function: builtin#91'
+ sync: 6
+...
+future = c:eval('return 123', {}, {is_async = true, skip_header = true, \
+ buffer = require('buffer').ibuf()})
+---
+...
+tostring(future)
+---
+- 'net.box.request: 7'
+...
+future:wait_result()
+---
+- 6
+...
+test_run:cmd("push filter '0x[a-f0-9]+' to '<addr>'")
+---
+- true
+...
+future
+---
+- method: eval
+ result: 6
+ on_push_ctx: []
+ buffer:
+ ibuf:
+ rpos: 'cdata<char *>: <addr>'
+ wpos: 'cdata<char *>: <addr>'
+ on_push: 'function: builtin#91'
+ sync: 7
+ skip_header: true
+...
+test_run:cmd("clear filter")
+---
+- true
+...
+box.schema.user.revoke('guest', 'execute', 'universe')
---
...
c:close()
diff --git a/test/box/net.box_fiber-async_gh-3107.test.lua b/test/box/net.box_fiber-async_gh-3107.test.lua
index d23f368cbce4..55f9afabad10 100644
--- a/test/box/net.box_fiber-async_gh-3107.test.lua
+++ b/test/box/net.box_fiber-async_gh-3107.test.lua
@@ -1,3 +1,5 @@
+test_run = require('test_run').new()
+
fiber = require 'fiber'
net = require('net.box')
@@ -5,8 +7,7 @@ net = require('net.box')
-- gh-3107: fiber-async netbox.
--
cond = nil
-box.schema.func.create('long_function')
-box.schema.user.grant('guest', 'execute', 'function', 'long_function')
+box.schema.user.grant('guest', 'execute', 'universe')
function long_function(...) cond = fiber.cond() cond:wait() return ... end
function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end
s = box.schema.create_space('test')
@@ -36,7 +37,28 @@ err:find('Usage') ~= nil
_, err = pcall(future.wait_result, future, '100')
err:find('Usage') ~= nil
-box.schema.func.drop('long_function')
+--
+-- __serialize and __tostring future methods
+--
+future = c:call('long_function', {1, 2, 3}, {is_async = true})
+tostring(future)
+future
+finalize_long()
+future:wait_result()
+future
+future = c:eval('assert(false)', {}, {is_async = true})
+tostring(future)
+future:wait_result()
+future
+future = c:eval('return 123', {}, {is_async = true, skip_header = true, \
+ buffer = require('buffer').ibuf()})
+tostring(future)
+future:wait_result()
+test_run:cmd("push filter '0x[a-f0-9]+' to '<addr>'")
+future
+test_run:cmd("clear filter")
+
+box.schema.user.revoke('guest', 'execute', 'universe')
c:close()
s:drop()
--
2.25.1
More information about the Tarantool-patches
mailing list