<HTML><BODY>Hi,<br>overall patch looks good with minor fixes (short summary, see explanation below):<br>- fix commit message<br>- change function name<br>- remove unused header<br><br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">
Четверг, 14 июня 2018, 18:04 +03:00 от Ilya Markov <imarkov@tarantool.org>:<br><br><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15289886910000000571_BODY">Add required for trigger on_ctl_event<br>
structures and lua bindings.<br><br>
Prerequisite #3259</div></div></div></div></blockquote>#3159<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15289886910000000571_BODY"><br>
---<br>
src/box/CMakeLists.txt | 1 +<br>
src/box/box.cc | 9 ++++++<br>
src/box/box.h | 1 +<br>
src/box/ctl.c | 63 +++++++++++++++++++++++++++++++++++++<br>
src/box/ctl.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++<br>
src/box/lua/cfg.cc | 12 +++++++<br>
src/box/lua/ctl.c | 51 ++++++++++++++++++++++++++++++<br>
src/box/lua/ctl.h | 2 ++<br>
src/box/lua/load_cfg.lua | 10 +++++-<br>
src/cfg.c | 37 ++++++++++++++++++++++<br>
src/cfg.h | 4 +++<br>
11 files changed, 270 insertions(+), 1 deletion(-)<br>
create mode 100644 src/box/ctl.c<br>
create mode 100644 src/box/ctl.h<br><br>
diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt<br>
index 6b1ae3e..74f6b54 100644<br>
--- a/src/box/CMakeLists.txt<br>
+++ b/src/box/CMakeLists.txt<br>
@@ -112,6 +112,7 @@ add_library(box STATIC<br>
journal.c<br>
wal.c<br>
call.c<br>
+ ctl.c<br>
${lua_sources}<br>
lua/init.c<br>
lua/call.c<br>
diff --git a/src/box/box.cc b/src/box/box.cc<br>
index 61bfa11..26277e7 100644<br>
--- a/src/box/box.cc<br>
+++ b/src/box/box.cc<br>
@@ -72,6 +72,7 @@<br>
#include "call.h"<br>
#include "func.h"<br>
#include "sequence.h"<br>
+#include "ctl.h"<br><br>
static char status[64] = "unknown";<br><br>
@@ -823,6 +824,13 @@ box_set_net_msg_max(void)<br>
IPROTO_FIBER_POOL_SIZE_FACTOR);<br>
}<br><br>
+void<br>
+box_set_on_ctl_event(void)<br>
+{<br>
+ if (cfg_reset_on_ctl_event() < 0)<br>
+ diag_raise();<br>
+}</div></div></div></div></blockquote>Please add _xc suffix, since function raise exception.<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15289886910000000571_BODY"><br>
+<br>
/* }}} configuration bindings */<br><br>
/**<br>
@@ -1808,6 +1816,7 @@ box_cfg_xc(void)<br>
box_set_replication_connect_timeout();<br>
box_set_replication_connect_quorum();<br>
box_set_replication_skip_conflict();<br>
+ box_set_on_ctl_event();<br>
replication_sync_lag = box_check_replication_sync_lag();<br>
xstream_create(&join_stream, apply_initial_join_row);<br>
xstream_create(&subscribe_stream, apply_row);<br>
diff --git a/src/box/box.h b/src/box/box.h<br>
index d396789..0325527 100644<br>
--- a/src/box/box.h<br>
+++ b/src/box/box.h<br>
@@ -191,6 +191,7 @@ void box_set_replication_connect_timeout(void);<br>
void box_set_replication_connect_quorum(void);<br>
void box_set_replication_skip_conflict(void);<br>
void box_set_net_msg_max(void);<br>
+void box_set_on_ctl_event(void);<br><br>
extern "C" {<br>
#endif /* defined(__cplusplus) */<br>
diff --git a/src/box/ctl.c b/src/box/ctl.c<br>
new file mode 100644<br>
index 0000000..fc3ae37<br>
--- /dev/null<br>
+++ b/src/box/ctl.c<br>
@@ -0,0 +1,63 @@<br>
+/*<br>
+ * Copyright 2010-2018, Tarantool AUTHORS, please see AUTHORS file.<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or<br>
+ * without modification, are permitted provided that the following<br>
+ * conditions are met:<br>
+ *<br>
+ * 1. Redistributions of source code must retain the above<br>
+ * copyright notice, this list of conditions and the<br>
+ * following disclaimer.<br>
+ *<br>
+ * 2. Redistributions in binary form must reproduce the above<br>
+ * copyright notice, this list of conditions and the following<br>
+ * disclaimer in the documentation and/or other materials<br>
+ * provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND<br>
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED<br>
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR<br>
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL<br>
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,<br>
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL<br>
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR<br>
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF<br>
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br>
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF<br>
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF<br>
+ * SUCH DAMAGE.<br>
+ */<br>
+#include <lib/small/small/rlist.h><br>
+#include <trigger.h><br>
+#include <box/ctl.h><br>
+#include "errcode.h"<br>
+#include "error.h"<br>
+#include <exception.h><br>
+<br>
+RLIST_HEAD(on_ctl_event);<br>
+<br>
+int<br>
+run_on_ctl_event_triggers(const struct on_ctl_event_ctx *result) {<br>
+ return trigger_run(&on_ctl_event, (void *) result);<br>
+}<br>
+<br>
+int<br>
+run_on_ctl_event_trigger_type(enum ctl_event_type type)<br>
+{<br>
+ struct on_ctl_event_ctx ctx = {};<br>
+ ctx.type = type;<br>
+ return run_on_ctl_event_triggers(&ctx);<br>
+}<br>
+<br>
+int<br>
+cfg_reset_on_ctl_event()<br>
+{<br>
+ if (cfg_reset_trigger("on_ctl_event", &on_ctl_event,<br>
+ lbox_push_on_ctl_event, NULL) < 0) {<br>
+ diag_set(ClientError, ER_CFG, "on_ctl_event",<br>
+ "expected function or table");<br>
+ return -1;<br>
+ }<br>
+ return 0;<br>
+}<br>
\ No newline at end of file<br>
diff --git a/src/box/ctl.h b/src/box/ctl.h<br>
new file mode 100644<br>
index 0000000..1dbb6be<br>
--- /dev/null<br>
+++ b/src/box/ctl.h<br>
@@ -0,0 +1,81 @@<br>
+#ifndef INCLUDES_TARANTOOL_CTL_H<br>
+#define INCLUDES_TARANTOOL_CTL_H<br>
+<br>
+/*<br>
+ * Copyright 2010-2018, Tarantool AUTHORS, please see AUTHORS file.<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or<br>
+ * without modification, are permitted provided that the following<br>
+ * conditions are met:<br>
+ *<br>
+ * 1. Redistributions of source code must retain the above<br>
+ * copyright notice, this list of conditions and the<br>
+ * following disclaimer.<br>
+ *<br>
+ * 2. Redistributions in binary form must reproduce the above<br>
+ * copyright notice, this list of conditions and the following<br>
+ * disclaimer in the documentation and/or other materials<br>
+ * provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND<br>
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED<br>
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR<br>
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL<br>
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,<br>
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL<br>
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR<br>
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF<br>
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br>
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF<br>
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF<br>
+ * SUCH DAMAGE.<br>
+ */<br>
+<br>
+#include <cfg.h><br>
+#include <box/lua/ctl.h></div></div></div></div></blockquote><br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15289886910000000571_BODY"><br>
+#include "errcode.h"<br>
+#include "error.h"<br>
+#include <exception.h></div></div></div></div></blockquote><br>I think last three headers are useless here.<br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_15289886910000000571_BODY"><br>
+<br>
+/** Global on-ctl_event triggers. */<br>
+extern struct rlist on_ctl_event;<br>
+<br>
+enum ctl_event_type {<br>
+ CTL_EVENT_SYSTEM_SPACE_RECOVERY,<br>
+ CTL_EVENT_LOCAL_RECOVERY,<br>
+ CTL_EVENT_READ_ONLY,<br>
+ CTL_EVENT_READ_WRITE,<br>
+ CTL_EVENT_SHUTDOWN,<br>
+ CTL_EVENT_REPLICASET_ADD,<br>
+ CTL_EVENT_REPLICASET_REMOVE,<br>
+};<br>
+<br>
+struct on_ctl_event_ctx {<br>
+ enum ctl_event_type type;<br>
+ uint32_t replica_id;<br>
+};<br>
+<br>
+#if defined(__cplusplus)<br>
+extern "C" {<br>
+#endif /* defined(__cplusplus) */<br>
+<br>
+/**<br>
+ * Runs on_ctl_event triggers with specified context.<br>
+ */<br>
+int<br>
+run_on_ctl_event_triggers(const struct on_ctl_event_ctx *result);<br>
+<br>
+/**<br>
+ * Runs on_ctl_event triggers with specified type.<br>
+ */<br>
+int<br>
+run_on_ctl_event_trigger_type(enum ctl_event_type type);<br>
+<br>
+int<br>
+cfg_reset_on_ctl_event();<br>
+#if defined(__cplusplus)<br>
+} /* extern "C" */<br>
+#endif /* defined(__cplusplus) */<br>
+<br>
+#endif /* INCLUDES_TARANTOOL_LUA_CTL_H */<br>
diff --git a/src/box/lua/cfg.cc b/src/box/lua/cfg.cc<br>
index 5afebc9..c92478f 100644<br>
--- a/src/box/lua/cfg.cc<br>
+++ b/src/box/lua/cfg.cc<br>
@@ -254,6 +254,17 @@ lbox_cfg_set_net_msg_max(struct lua_State *L)<br>
}<br><br>
static int<br>
+lbox_cfg_set_on_ctl_event(struct lua_State *L)<br>
+{<br>
+ try {<br>
+ box_set_on_ctl_event();<br>
+ } catch (Exception *) {<br>
+ luaT_error(L);<br>
+ }<br>
+ return 0;<br>
+}<br>
+<br>
+static int<br>
lbox_cfg_set_worker_pool_threads(struct lua_State *L)<br>
{<br>
(void) L;<br>
@@ -331,6 +342,7 @@ box_lua_cfg_init(struct lua_State *L)<br>
{"cfg_set_replication_skip_conflict", lbox_cfg_set_replication_skip_conflict},<br>
{"cfg_set_replication_connect_timeout", lbox_cfg_set_replication_connect_timeout},<br>
{"cfg_set_net_msg_max", lbox_cfg_set_net_msg_max},<br>
+ {"cfg_set_on_ctl_event", lbox_cfg_set_on_ctl_event},<br>
{NULL, NULL}<br>
};<br><br>
diff --git a/src/box/lua/ctl.c b/src/box/lua/ctl.c<br>
index 9a105ed..52f320a 100644<br>
--- a/src/box/lua/ctl.c<br>
+++ b/src/box/lua/ctl.c<br>
@@ -35,6 +35,8 @@<br>
#include <lua.h><br>
#include <lauxlib.h><br>
#include <lualib.h><br>
+#include <lua/trigger.h><br>
+#include <box/ctl.h><br><br>
#include "lua/utils.h"<br><br>
@@ -64,9 +66,37 @@ lbox_ctl_wait_rw(struct lua_State *L)<br>
return 0;<br>
}<br><br>
+<br>
+int<br>
+lbox_push_on_ctl_event(struct lua_State *L, void *event)<br>
+{<br>
+ struct on_ctl_event_ctx *ctx = (struct on_ctl_event_ctx *) event;<br>
+ lua_newtable(L);<br>
+ lua_pushstring(L, "type");<br>
+ lua_pushinteger(L, ctx->type);<br>
+ lua_settable(L, -3);<br>
+<br>
+ if (ctx->type == CTL_EVENT_REPLICASET_ADD ||<br>
+ ctx->type == CTL_EVENT_REPLICASET_REMOVE) {<br>
+ lua_pushstring(L, "replica_id");<br>
+ luaL_pushuint64(L, ctx->replica_id);<br>
+ lua_settable(L, -3);<br>
+ }<br>
+ return 1;<br>
+}<br>
+<br>
+static int<br>
+lbox_on_ctl_event(struct lua_State *L)<br>
+{<br>
+ return lbox_trigger_reset(L, 2, &on_ctl_event,<br>
+ lbox_push_on_ctl_event, NULL);<br>
+}<br>
+<br>
+<br>
static const struct luaL_Reg lbox_ctl_lib[] = {<br>
{"wait_ro", lbox_ctl_wait_ro},<br>
{"wait_rw", lbox_ctl_wait_rw},<br>
+ {"on_ctl_event", lbox_on_ctl_event},<br>
{NULL, NULL}<br>
};<br><br>
@@ -75,4 +105,25 @@ box_lua_ctl_init(struct lua_State *L)<br>
{<br>
luaL_register_module(L, "box.ctl", lbox_ctl_lib);<br>
lua_pop(L, 1);<br>
+<br>
+ luaL_findtable(L, LUA_GLOBALSINDEX, "box.ctl", 1);<br>
+ lua_newtable(L);<br>
+ lua_setfield(L, -2, "event");<br>
+ lua_getfield(L, -1, "event");<br>
+<br>
+ lua_pushnumber(L, CTL_EVENT_SYSTEM_SPACE_RECOVERY);<br>
+ lua_setfield(L, -2, "SYSTEM_SPACE_RECOVERY");<br>
+ lua_pushnumber(L, CTL_EVENT_LOCAL_RECOVERY);<br>
+ lua_setfield(L, -2, "LOCAL_RECOVERY");<br>
+ lua_pushnumber(L, CTL_EVENT_READ_ONLY);<br>
+ lua_setfield(L, -2, "READ_ONLY");<br>
+ lua_pushnumber(L, CTL_EVENT_READ_WRITE);<br>
+ lua_setfield(L, -2, "READ_WRITE");<br>
+ lua_pushnumber(L, CTL_EVENT_SHUTDOWN);<br>
+ lua_setfield(L, -2, "SHUTDOWN");<br>
+ lua_pushnumber(L, CTL_EVENT_REPLICASET_ADD);<br>
+ lua_setfield(L, -2, "CTL_EVENT_REPLICASET_ADD");<br>
+ lua_pushnumber(L, CTL_EVENT_REPLICASET_REMOVE);<br>
+ lua_setfield(L, -2, "CTL_EVENT_REPLICASET_REMOVE");<br>
+ lua_pop(L, 2); /* box, ctl */<br>
}<br>
diff --git a/src/box/lua/ctl.h b/src/box/lua/ctl.h<br>
index e7c2edd..ab63232 100644<br>
--- a/src/box/lua/ctl.h<br>
+++ b/src/box/lua/ctl.h<br>
@@ -41,6 +41,8 @@ struct lua_State;<br>
void<br>
box_lua_ctl_init(struct lua_State *L);<br><br>
+int<br>
+lbox_push_on_ctl_event(struct lua_State *L, void *event);<br>
#if defined(__cplusplus)<br>
} /* extern "C" */<br>
#endif /* defined(__cplusplus) */<br>
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua<br>
index 0b668cd..c4d1347 100644<br>
--- a/src/box/lua/load_cfg.lua<br>
+++ b/src/box/lua/load_cfg.lua<br>
@@ -1,7 +1,11 @@<br>
-- load_cfg.lua - internal file<br><br>
local log = require('log')<br>
-local json = require('json')<br>
+local json = require("json").new()<br>
+json.cfg{<br>
+ encode_use_tostring = true,<br>
+}<br>
+<br>
local private = require('box.internal')<br>
local urilib = require('uri')<br>
local math = require('math')<br>
@@ -64,6 +68,7 @@ local default_cfg = {<br>
feedback_host = "<a href="https://feedback.tarantool.io" target="_blank">https://feedback.tarantool.io</a>",<br>
feedback_interval = 3600,<br>
net_msg_max = 768,<br>
+ on_ctl_event = nil,<br>
}<br><br>
-- types of available options<br>
@@ -125,6 +130,7 @@ local template_cfg = {<br>
feedback_host = 'string',<br>
feedback_interval = 'number',<br>
net_msg_max = 'number',<br>
+ on_ctl_event = 'function, table',<br>
}<br><br>
local function normalize_uri(port)<br>
@@ -216,6 +222,7 @@ local dynamic_cfg = {<br>
replicaset_uuid = check_replicaset_uuid,<br>
replication_skip_conflict = private.cfg_set_replication_skip_conflict,<br>
net_msg_max = private.cfg_set_net_msg_max,<br>
+ on_ctl_event = private.cfg_set_on_ctl_event,<br>
}<br><br>
local dynamic_cfg_skip_at_load = {<br>
@@ -232,6 +239,7 @@ local dynamic_cfg_skip_at_load = {<br>
force_recovery = true,<br>
instance_uuid = true,<br>
replicaset_uuid = true,<br>
+ on_ctl_event = true,<br>
}<br><br>
local function convert_gb(size)<br>
diff --git a/src/cfg.c b/src/cfg.c<br>
index 7c7d6e7..b07c1f3 100644<br>
--- a/src/cfg.c<br>
+++ b/src/cfg.c<br>
@@ -153,3 +153,40 @@ cfg_getarr_elem(const char *name, int i)<br>
lua_pop(tarantool_L, 2);<br>
return val;<br>
}<br>
+<br>
+int<br>
+cfg_reset_trigger(const char *name, struct rlist *list,<br>
+ lbox_push_event_f push_event, lbox_pop_event_f pop_event)<br>
+{<br>
+ cfg_get(name);<br>
+ struct lua_State *L = tarantool_L;<br>
+ if (lua_isnil(L, -1))<br>
+ return 0;<br>
+ if (!lua_isfunction(L, -1) && !lua_istable(L, -1)) {<br>
+ return -1;<br>
+ }<br>
+ if (lua_istable(L, -1)) {<br>
+ lua_pushinteger(L, 1);<br>
+ lua_gettable(L, -2);<br>
+ if (!luaL_isnull(L, lua_gettop(L)) && !lua_isfunction(L, -1))<br>
+ return -1;<br>
+ bool is_nil = luaL_isnull(L, lua_gettop(L));<br>
+ if (is_nil) {<br>
+ lua_pop(L, 1);<br>
+ lua_pushnil(L);<br>
+ }<br>
+ lua_pushinteger(L, 2);<br>
+ lua_gettable(L, -3);<br>
+ if (!lua_isfunction(L, -1) && !lua_isnil(L, -1))<br>
+ return -1;<br>
+ if (is_nil && lua_isnil(L, -1)) {<br>
+ return 0;<br>
+ }<br>
+ } else {<br>
+ lua_pushnil(L);<br>
+ }<br>
+ int rc = lbox_trigger_reset(L, lua_gettop(L), list,<br>
+ push_event, pop_event);<br>
+ lua_pop(L, 1);<br>
+ return rc;<br>
+}<br>
\ No newline at end of file<br>
diff --git a/src/cfg.h b/src/cfg.h<br>
index <span class="js-phone-number">8499388</span>..d36465c 100644<br>
--- a/src/cfg.h<br>
+++ b/src/cfg.h<br>
@@ -32,6 +32,7 @@<br>
*/<br><br>
#include <stdint.h><br>
+#include <lua/trigger.h><br><br>
#if defined(__cplusplus)<br>
extern "C" {<br>
@@ -61,6 +62,9 @@ cfg_getarr_size(const char *name);<br>
const char *<br>
cfg_getarr_elem(const char *name, int i);<br><br>
+int<br>
+cfg_reset_trigger(const char *name, struct rlist *list,<br>
+ lbox_push_event_f push_event, lbox_pop_event_f pop_event);<br>
#if defined(__cplusplus)<br>
} /* extern "C" */<br>
#endif /* defined(__cplusplus) */<br>
-- <br>
2.7.4<br><br><br></div></div></div></div></blockquote>
<br>
<br>Best regards,<br>Konstantin Belyavskiy<br>k.belyavskiy@tarantool.org<br></BODY></HTML>