* [tarantool-patches] [PATCH] Add a way to know instance is being run or restarted by tarantoolctl.
@ 2018-07-01 21:40 Serge Petrenko
0 siblings, 0 replies; only message in thread
From: Serge Petrenko @ 2018-07-01 21:40 UTC (permalink / raw)
To: tarantool-patches; +Cc: Serge Petrenko
There are some hacks to know the instance was run by tarantoolctl,
none of them are too reliable, thoug. This patch adds a convenient
way to know whether instance is being run or restarted by tarantoolctl.
For this purpose, we intoduce 2 new fields to box.info table:
box.info.tarantoolctl and box.info.is_restart, set to true, respectively,
if the instance is being run by tarantoolctl, and if it is being restarted.
Closes: #3215
---
https://github.com/tarantool/tarantool/tree/sergepetrenko/gh-3215-tarantoolctl-detection
https://github.com/tarantool/tarantool/issues/3215
| 9 +++++++++
src/box/lua/info.c | 15 +++++++++++++++
src/main.cc | 37 +++++++++++++++++++++++++++++++++++++
src/main.h | 12 ++++++++++++
test/box/info.result | 10 ++++++++++
test/box/info.test.lua | 2 ++
6 files changed, 85 insertions(+)
--git a/extra/dist/tarantoolctl.in b/extra/dist/tarantoolctl.in
index b6b8e09c9..e3212c14a 100755
--- a/extra/dist/tarantoolctl.in
+++ b/extra/dist/tarantoolctl.in
@@ -22,6 +22,7 @@ int kill(int pid, int sig);
int isatty(int fd);
int getppid(void);
int chdir(const char *path);
+int setenv(const char *name, const char *value, int overwrite);
]]
local TIMEOUT_INFINITY = 100 * 365 * 86400
@@ -509,6 +510,11 @@ local function start()
log.error("The daemon is already running: PID %s", pid)
os.exit(1)
end
+
+ -- Set an environment variable for tarantool
+ -- to know it's being run under tarantoolctl.
+ ffi.C.setenv('TARANTOOLCTL', 'true', 0)
+
box.cfg = wrapper_cfg
require('title').update{
script_name = instance_path,
@@ -593,6 +599,9 @@ local function restart()
end
stop()
fiber.sleep(1)
+ -- Set an environment variable for tarantool to
+ -- know it's being restarted by tarantoolctl.
+ ffi.C.setenv('TARANTOOL_RESTART', 'true', 0)
start()
return 0
end
diff --git a/src/box/lua/info.c b/src/box/lua/info.c
index d6697df9c..9b29d1320 100644
--- a/src/box/lua/info.c
+++ b/src/box/lua/info.c
@@ -246,6 +246,19 @@ lbox_info_ro(struct lua_State *L)
return 1;
}
+static int
+lbox_info_tarantoolctl(struct lua_State *L)
+{
+ lua_pushboolean(L, tarantool_under_tarantoolctl());
+ return 1;
+}
+
+static int
+lbox_info_is_restart(struct lua_State *L)
+{
+ lua_pushboolean(L, tarantool_is_restart());
+ return 1;
+}
/*
* Tarantool 1.6.x compat
*/
@@ -530,6 +543,8 @@ static const struct luaL_Reg lbox_info_dynamic_meta[] = {
{"signature", lbox_info_signature},
{"vclock", lbox_info_vclock},
{"ro", lbox_info_ro},
+ {"tarantoolctl", lbox_info_tarantoolctl},
+ {"is_restart", lbox_info_is_restart},
{"replication", lbox_info_replication},
{"status", lbox_info_status},
{"uptime", lbox_info_uptime},
diff --git a/src/main.cc b/src/main.cc
index a36a2b0d0..888926ec3 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -87,14 +87,41 @@ static int main_argc;
static ev_signal ev_sigs[6];
static const int ev_sig_count = sizeof(ev_sigs)/sizeof(*ev_sigs);
+static bool under_tarantoolctl;
+static bool is_restart;
+
static double start_time;
+bool
+tarantool_under_tarantoolctl()
+{
+ return under_tarantoolctl;
+}
+
+bool
+tarantool_is_restart()
+{
+ return is_restart;
+}
+
double
tarantool_uptime(void)
{
return ev_monotonic_now(loop()) - start_time;
}
+/**
+ * Check if the instance is being run or restarted
+ * by tarantoolctl. In case it is, there will be
+ * TARANTOOLCTL (and maybe TARANTOOL_RESTART) environment
+ * variable set for us by tarantoolctl.
+ */
+void detect_tarantoolctl()
+{
+ under_tarantoolctl = getenv("TARANTOOLCTL") != NULL;
+ is_restart = getenv("TARANTOOL_RESTART") != NULL;
+}
+
/**
* Create a checkpoint from signal handler (SIGUSR1)
*/
@@ -523,6 +550,16 @@ load_cfg()
title_set_custom(cfg_gets("custom_proc_title"));
title_update();
box_cfg();
+
+ /*
+ * tarantoolctl is a lua script executed by tarantool,
+ * so the only valid place in tarantool to detect
+ * tarantoolctl's presence is after the call to
+ * tarantool_lua_run_script(), but before user code
+ * execution. Doing it right after user calls
+ * box.cfg{} seems to be the only way out.
+ */
+ detect_tarantoolctl();
}
void
diff --git a/src/main.h b/src/main.h
index 221374144..c69b6a912 100644
--- a/src/main.h
+++ b/src/main.h
@@ -37,6 +37,18 @@
extern "C" {
#endif /* defined(__cplusplus) */
+/**
+ * Returns whether instance was run by tarantoolctl.
+ */
+bool
+tarantool_under_tarantoolctl();
+
+/**
+ * Returns whether the instance was restarted by tarantoolctl.
+ */
+bool
+tarantool_is_restart();
+
double tarantool_uptime(void);
void
diff --git a/test/box/info.result b/test/box/info.result
index 338463155..5b7a827bf 100644
--- a/test/box/info.result
+++ b/test/box/info.result
@@ -51,6 +51,14 @@ box.info.status
---
- running
...
+box.info.tarantoolctl == true or box.info
+---
+- true
+...
+box.info.is_restart == false or box.info
+---
+- true
+...
string.len(box.info.uptime) > 0
---
- true
@@ -77,6 +85,7 @@ t
- - cluster
- gc
- id
+ - is_restart
- lsn
- memory
- pid
@@ -84,6 +93,7 @@ t
- ro
- signature
- status
+ - tarantoolctl
- uptime
- uuid
- vclock
diff --git a/test/box/info.test.lua b/test/box/info.test.lua
index 60ee3216d..828e21c56 100644
--- a/test/box/info.test.lua
+++ b/test/box/info.test.lua
@@ -14,6 +14,8 @@ box.info.signature >= 0
box.info.ro == false
box.info.replication[1].id
box.info.status
+box.info.tarantoolctl == true or box.info
+box.info.is_restart == false or box.info
string.len(box.info.uptime) > 0
string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil
box.info.cluster.uuid == box.space._schema:get{'cluster'}[2]
--
2.15.2 (Apple Git-101.1)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2018-07-01 21:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-01 21:40 [tarantool-patches] [PATCH] Add a way to know instance is being run or restarted by tarantoolctl Serge Petrenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox