Project

General

Profile

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

mackyle, 2016-02-27 21:35

 
From f0d14f4c9bc233bb8a125fdbfbb03a5cb56d62a4 Mon Sep 17 00:00:00 2001
From: "Kyle J. McKay" <mackyle@gmail.com>
Date: Sat, 27 Feb 2016 13:23:49 -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 517a025e..1f7e2a23 100644
--- a/src/server.c
+++ b/src/server.c
@@ -559,6 +559,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" \
@@ -581,6 +582,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
@@ -616,7 +619,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) {
@@ -634,6 +637,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;
@@ -1519,6 +1534,7 @@ int main (int argc, char **argv) {
"polls:", n);
}
#endif
+ server_activity = time(NULL);
fd_ndx = -1;
do {
fdevent_handler handler;
@@ -1559,6 +1575,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;
@@ -1583,16 +1606,21 @@ int main (int argc, char **argv) {
if (0 == graceful_shutdown)
remove_pid_file(srv, &pid_fd);
+ 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.6.5

(3-3/4)