From 357f15517898ad218393d11c32cde16f2cb49a9f Mon Sep 17 00:00:00 2001
From: mechanik20051988 <mechanik20.05.1988@gmail.com>
Date: Fri, 5 Mar 2021 16:00:09 +0300
Subject: [PATCH] lua: change on_shutdown triggers behaviour

Previously lua on_shutdown triggers were started sequentially, now
each of triggers starts in a separate fiber. Tarantool waits for 3.0
seconds to their completion by default. User has the option to change
this value using new implemented box.ctl.set_on_shutdown_timeout function.
If timeout has expired, tarantool immediately stops, without waiting for
other triggers completion.
Also moved ev_break from trigger to the on_shutdown_f function, after
calling all on_shutdown lua triggers, because now all triggers are
started asynchronously in fibers, and we should call ev_break only
after all triggers are finished.

Part of #5723

@TarantoolBot document
Title: Changed Lua on_shutdown triggers behaviour.
Previously lua on_shutdown triggers were started sequentially, now
each of triggers starts in a separate fiber. Tarantool waits for 3.0
seconds to their completion by default. User has the option to change
this value using new implemented box.ctl.set_on_shutdown_timeout function.
If timeout has expired, tarantool immediately stops, without waiting for
other triggers completion.
---
 ...ange-lua-on-shutdown-triggers-behaviour.md |  8 +++++++
 src/box/box.cc                                |  2 ++
 src/box/box.h                                 |  3 +++
 src/box/lua/ctl.c                             | 21 +++++++++++++++++++
 src/main.cc                                   | 20 +++---------------
 5 files changed, 37 insertions(+), 17 deletions(-)
 create mode 100644 changelogs/unreleased/change-lua-on-shutdown-triggers-behaviour.md

diff --git a/changelogs/unreleased/change-lua-on-shutdown-triggers-behaviour.md b/changelogs/unreleased/change-lua-on-shutdown-triggers-behaviour.md
new file mode 100644
index 0000000000..bd9159b684
--- /dev/null
+++ b/changelogs/unreleased/change-lua-on-shutdown-triggers-behaviour.md
@@ -0,0 +1,8 @@
+## feature/core
+
+*  Previously lua on_shutdown triggers were started sequentially, now
+   each of triggers starts in a separate fiber. Tarantool waits for 3.0
+   seconds to their completion by default. User has the option to change
+   this value using new implemented box.ctl.set_on_shutdown_timeout function.
+   If timeout has expired, tarantool immediately stops, without waiting for
+   other triggers completion.
diff --git a/src/box/box.cc b/src/box/box.cc
index b2a72e1e37..178dd5bd65 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -88,6 +88,8 @@ static char status[64] = "unknown";
 /** box.stat rmean */
 struct rmean *rmean_box;
 
+double on_shutdown_trigger_timeout = 3.0;
+
 struct rlist box_on_shutdown_trigger_list =
 	RLIST_HEAD_INITIALIZER(box_on_shutdown_trigger_list);
 
diff --git a/src/box/box.h b/src/box/box.h
index ad5c12e317..9a5ce91e8e 100644
--- a/src/box/box.h
+++ b/src/box/box.h
@@ -64,6 +64,9 @@ struct vclock;
  */
 extern const struct vclock *box_vclock;
 
+/** Time to wait for shutdown triggers finished */
+extern double on_shutdown_trigger_timeout;
+
 /** Invoked on box shutdown. */
 extern struct rlist box_on_shutdown_trigger_list;
 
diff --git a/src/box/lua/ctl.c b/src/box/lua/ctl.c
index ea0154f07a..d039a059fe 100644
--- a/src/box/lua/ctl.c
+++ b/src/box/lua/ctl.c
@@ -99,6 +99,26 @@ lbox_ctl_is_recovery_finished(struct lua_State *L)
 	return 1;
 }
 
+static int
+lbox_ctl_set_on_shutdown_timeout(struct lua_State *L)
+{
+	int index = lua_gettop(L);
+	if (index != 1) {
+		lua_pushstring(L, "function expected one argument");
+		lua_error(L);
+	}
+
+	double wait_time = luaL_checknumber(L, 1);
+	if (wait_time <= 0) {
+		lua_pushstring(L, "on_shutdown timeout must be greater "
+			       "then zero");
+		lua_error(L);
+	}
+
+	on_shutdown_trigger_timeout = wait_time;
+	return 0;
+}
+
 static const struct luaL_Reg lbox_ctl_lib[] = {
 	{"wait_ro", lbox_ctl_wait_ro},
 	{"wait_rw", lbox_ctl_wait_rw},
@@ -106,6 +126,7 @@ static const struct luaL_Reg lbox_ctl_lib[] = {
 	{"on_schema_init", lbox_ctl_on_schema_init},
 	{"clear_synchro_queue", lbox_ctl_clear_synchro_queue},
 	{"is_recovery_finished", lbox_ctl_is_recovery_finished},
+	{"set_on_shutdown_timeout", lbox_ctl_set_on_shutdown_timeout},
 	{NULL, NULL}
 };
 
diff --git a/src/main.cc b/src/main.cc
index 127114cc69..2be048d775 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -99,8 +99,6 @@ static double start_time;
 static struct fiber *on_shutdown_fiber = NULL;
 /** A flag restricting repeated execution of tarantool_exit(). */
 static bool is_shutting_down = false;
-/** A trigger which will break the event loop on shutdown. */
-static struct trigger break_loop_trigger;
 static int exit_code = 0;
 
 double
@@ -137,7 +135,9 @@ static int
 on_shutdown_f(va_list ap)
 {
 	(void) ap;
-	trigger_run(&box_on_shutdown_trigger_list, NULL);
+	trigger_fiber_run(&box_on_shutdown_trigger_list, NULL,
+			  on_shutdown_trigger_timeout);
+	ev_break(loop(), EVBREAK_ALL);
 	return 0;
 }
 
@@ -582,13 +582,6 @@ print_help(const char *program)
 	puts("to see online documentation, submit bugs or contribute a patch.");
 }
 
-static int
-break_loop(struct trigger *, void *)
-{
-	ev_break(loop(), EVBREAK_ALL);
-	return 0;
-}
-
 extern "C" void **
 export_syms(void);
 
@@ -741,13 +734,6 @@ main(int argc, char **argv)
 						 on_shutdown_f);
 		if (on_shutdown_fiber == NULL)
 			diag_raise();
-		/*
-		 * Register a on_shutdown trigger which will break the
-		 * main event loop. The trigger will be the last to run
-		 * since it's the first one we register.
-		 */
-		trigger_create(&break_loop_trigger, break_loop, NULL, NULL);
-		trigger_add(&box_on_shutdown_trigger_list, &break_loop_trigger);
 
 		/*
 		 * The call to tarantool_free() below, thanks to
-- 
GitLab