Project

General

Profile

Feature #2696 » 0005-server.c-support-i-secs-idle-timeout-option_patch.txt

mackyle, 2015-12-05 01:23

 
From adedac4902838db25ae8897337674ac334e61126 Mon Sep 17 00:00:00 2001
From: "Kyle J. McKay" <mackyle@gmail.com>
Date: Fri, 4 Dec 2015 16:45:26 -0800
Subject: [PATCH] server.c: support -i <secs> idle timeout option

After <secs> of no activity the server will initiate a graceful
shutdown. Defaults to off (0).

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
---
src/server.c | 44 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/server.c b/src/server.c
index 2764c9a5..d36fce18 100644
--- a/src/server.c
+++ b/src/server.c
@@ -531,6 +531,7 @@ static void show_help (void) {
"usage:\n" \
" -f <name> filename of the config-file\n" \
" -m <name> module directory (default: "LIBRARY_DIR")\n" \
+" -i <secs> graceful shutdown after <secs> of inactivity\n" \
" -p print the parsed config-file in internal form, and exit\n" \
" -t test the config-file, and exit\n" \
" -D don't go to background (default: go to background)\n" \
@@ -553,6 +554,8 @@ int main (int argc, char **argv) {
int num_childs = 0;
int pid_fd = -1, fd;
size_t i;
+ time_t idle_timeout = 0, server_activity = time(NULL);
+ int timed_out = 0;
#ifdef HAVE_SIGACTION
struct sigaction act;
#endif
@@ -588,7 +591,7 @@ int main (int argc, char **argv) {
#endif
srv->srvconf.dont_daemonize = 0;
- while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
+ while(-1 != (o = getopt(argc, argv, "f:m:i:hvVDpt"))) {
switch(o) {
case 'f':
if (srv->config_storage) {
@@ -606,6 +609,18 @@ int main (int argc, char **argv) {
case 'm':
buffer_copy_string(srv->srvconf.modules_dir, optarg);
break;
+ case 'i': {
+ char *endptr;
+ long timeout = strtol(optarg, &endptr, 0);
+ if (!*optarg || *endptr || timeout < 0) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "Invalid idle timeout value:", optarg);
+ server_free(srv);
+ return -1;
+ }
+ idle_timeout = (time_t)timeout;
+ break;
+ }
case 'p': print_config = 1; break;
case 't': test_config = 1; break;
case 'D': srv->srvconf.dont_daemonize = 1; break;
@@ -1506,6 +1521,7 @@ int main (int argc, char **argv) {
"polls:", n);
}
#endif
+ server_activity = time(NULL);
fd_ndx = -1;
do {
fdevent_handler handler;
@@ -1546,6 +1562,13 @@ int main (int argc, char **argv) {
strerror(errno));
}
+ if (idle_timeout && !graceful_shutdown && time(NULL) - server_activity >= idle_timeout) {
+ log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_timeout,
+ "s exceeded, initiating graceful shutdown");
+ timed_out = 1;
+ graceful_shutdown = 1;
+ }
+
for (ndx = 0; ndx < srv->joblist->used; ndx++) {
connection *con = srv->joblist->ptr[ndx];
handler_t r;
@@ -1595,16 +1618,21 @@ int main (int argc, char **argv) {
}
}
+ if (timed_out) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "server stopped by idle timeout");
+ } else {
#ifdef HAVE_SIGACTION
- log_error_write(srv, __FILE__, __LINE__, "sdsd",
- "server stopped by UID =",
- last_sigterm_info.si_uid,
- "PID =",
- last_sigterm_info.si_pid);
+ log_error_write(srv, __FILE__, __LINE__, "sdsd",
+ "server stopped by UID =",
+ last_sigterm_info.si_uid,
+ "PID =",
+ last_sigterm_info.si_pid);
#else
- log_error_write(srv, __FILE__, __LINE__, "s",
- "server stopped");
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "server stopped");
#endif
+ }
/* clean-up */
log_error_close(srv);
--
2.4.10

(2-2/4)