Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH] net.box: add __serialize and __tostring methods for future objects
@ 2021-08-13 12:58 Vladimir Davydov via Tarantool-patches
  2021-08-13 17:41 ` Yaroslav Dynnikov via Tarantool-patches
  0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Davydov via Tarantool-patches @ 2021-08-13 12:58 UTC (permalink / raw)
  To: tarantool-patches; +Cc: v.shpilevoy, yaroslav.dynnikov

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


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-08-26 15:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-13 12:58 [Tarantool-patches] [PATCH] net.box: add __serialize and __tostring methods for future objects Vladimir Davydov via Tarantool-patches
2021-08-13 17:41 ` Yaroslav Dynnikov via Tarantool-patches
2021-08-17  7:58   ` Vladimir Davydov via Tarantool-patches
2021-08-17  8:00     ` [Tarantool-patches] [PATCH v2] " Vladimir Davydov via Tarantool-patches
2021-08-24 22:39       ` Vladislav Shpilevoy via Tarantool-patches
2021-08-25 13:35         ` Vladimir Davydov via Tarantool-patches
2021-08-25 20:08           ` Vladislav Shpilevoy via Tarantool-patches
2021-08-26 14:56           ` Yaroslav Dynnikov via Tarantool-patches
2021-08-26 15:05             ` Vladimir Davydov via Tarantool-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox