Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new options to control worker minimum and maximum lifetime #125

Merged
merged 1 commit into from
Jan 26, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions core/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ void uwsgi_init_default() {
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 4;
uwsgi.shared->options[UWSGI_OPTION_LOGGING] = 1;

uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME] = 60;

#ifdef UWSGI_SPOOLER
uwsgi.shared->spooler_frequency = 30;

Expand Down Expand Up @@ -418,6 +420,13 @@ void sanitize_args() {
uwsgi_log("caching of static paths requires uWSGI caching !!!\n");
exit(1);
}

if (uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] > 0 && uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME] >= uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME]) {
uwsgi_log("invalid min-worker-lifetime value (%d), must be lower than max-worker-lifetime (%d)\n",
uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME], uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME]);
exit(1);
}

}

const char *uwsgi_http_status_msg(char *status, uint16_t *len) {
Expand Down
9 changes: 9 additions & 0 deletions core/master.c
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,15 @@ int master_loop(char **argv, char **environ) {
uwsgi.workers[i].rss_size = 0;
}
}
// check if worker was running longer than allowed lifetime
if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cheaped == 0 && uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] > 0) {
uint64_t lifetime = uwsgi_now() - uwsgi.workers[i].last_spawn;
if (lifetime > uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] && uwsgi.workers[i].manage_next_request == 1) {
uwsgi_log("worker %d lifetime reached, it was running for %llu second(s)\n", i, (unsigned long long) lifetime);
uwsgi.workers[i].manage_next_request = 0;
kill(uwsgi.workers[i].pid, SIGWINCH);
}
}

// need to find a better way
//uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time;
Expand Down
13 changes: 9 additions & 4 deletions core/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,8 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
uwsgi_buffer_destroy(wsgi_req->headers);
}

wsgi_req->end_of_request = uwsgi_micros();
uint64_t end_of_request = uwsgi_micros();
wsgi_req->end_of_request = end_of_request;

tmp_rt = wsgi_req->end_of_request - wsgi_req->start_of_request;

Expand Down Expand Up @@ -690,15 +691,19 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
memset(wsgi_req, 0, sizeof(struct wsgi_request));
wsgi_req->async_id = tmp_id;

if (uwsgi.shared->options[UWSGI_OPTION_MAX_REQUESTS] > 0 && uwsgi.workers[uwsgi.mywid].delta_requests >= uwsgi.shared->options[UWSGI_OPTION_MAX_REQUESTS]) {
if (uwsgi.shared->options[UWSGI_OPTION_MAX_REQUESTS] > 0
&& uwsgi.workers[uwsgi.mywid].delta_requests >= uwsgi.shared->options[UWSGI_OPTION_MAX_REQUESTS]
&& (end_of_request - (uwsgi.workers[uwsgi.mywid].last_spawn*1000000) >= uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME]*1000000)) {
goodbye_cruel_world();
}

if (uwsgi.reload_on_as && (rlim_t) vsz >= uwsgi.reload_on_as) {
if (uwsgi.reload_on_as && (rlim_t) vsz >= uwsgi.reload_on_as
&& (end_of_request - (uwsgi.workers[uwsgi.mywid].last_spawn*1000000) >= uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME]*1000000)) {
goodbye_cruel_world();
}

if (uwsgi.reload_on_rss && (rlim_t) rss >= uwsgi.reload_on_rss) {
if (uwsgi.reload_on_rss && (rlim_t) rss >= uwsgi.reload_on_rss
&& (end_of_request - (uwsgi.workers[uwsgi.mywid].last_spawn*1000000) >= uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME]*1000000)) {
goodbye_cruel_world();
}

Expand Down
2 changes: 2 additions & 0 deletions core/uwsgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ static struct uwsgi_option uwsgi_base_options[] = {

{"reaper", no_argument, 'r', "call waitpid(-1,...) after each request to get rid of zombies", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_REAPER, 0},
{"max-requests", required_argument, 'R', "reload workers after the specified amount of managed requests", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_MAX_REQUESTS, 0},
{"min-worker-lifetime", required_argument, 0, "number of seconds worker must run before being reloaded (default is 60)", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_MIN_WORKER_LIFETIME, 0},
{"max-worker-lifetime", required_argument, 0, "reload workers after the specified amount of seconds (default is disabled)", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_MAX_WORKER_LIFETIME, 0},

{"socket-timeout", required_argument, 'z', "set internal sockets timeout", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_SOCKET_TIMEOUT, 0},
{"no-fd-passing", no_argument, 0, "disable file descriptor passing", uwsgi_opt_true, &uwsgi.no_fd_passing, 0},
Expand Down
46 changes: 24 additions & 22 deletions uwsgi.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,27 +653,29 @@ struct uwsgi_opt {
#include <machine/endian.h>
#endif

#define UWSGI_OPTION_LOGGING 0
#define UWSGI_OPTION_MAX_REQUESTS 1
#define UWSGI_OPTION_SOCKET_TIMEOUT 2
#define UWSGI_OPTION_MEMORY_DEBUG 3
#define UWSGI_OPTION_MASTER_INTERVAL 4
#define UWSGI_OPTION_HARAKIRI 5
#define UWSGI_OPTION_CGI_MODE 6
#define UWSGI_OPTION_THREADS 7
#define UWSGI_OPTION_REAPER 8
#define UWSGI_OPTION_LOG_ZERO 9
#define UWSGI_OPTION_LOG_SLOW 10
#define UWSGI_OPTION_LOG_4xx 11
#define UWSGI_OPTION_LOG_5xx 12
#define UWSGI_OPTION_LOG_BIG 13
#define UWSGI_OPTION_LOG_SENDFILE 14
#define UWSGI_OPTION_BACKLOG_STATUS 15
#define UWSGI_OPTION_BACKLOG_ERRORS 16
#define UWSGI_OPTION_SPOOLER_HARAKIRI 17
#define UWSGI_OPTION_MULE_HARAKIRI 18

#define UWSGI_SPOOLER_EXTERNAL 1
#define UWSGI_OPTION_LOGGING 0
#define UWSGI_OPTION_MAX_REQUESTS 1
#define UWSGI_OPTION_SOCKET_TIMEOUT 2
#define UWSGI_OPTION_MEMORY_DEBUG 3
#define UWSGI_OPTION_MASTER_INTERVAL 4
#define UWSGI_OPTION_HARAKIRI 5
#define UWSGI_OPTION_CGI_MODE 6
#define UWSGI_OPTION_THREADS 7
#define UWSGI_OPTION_REAPER 8
#define UWSGI_OPTION_LOG_ZERO 9
#define UWSGI_OPTION_LOG_SLOW 10
#define UWSGI_OPTION_LOG_4xx 11
#define UWSGI_OPTION_LOG_5xx 12
#define UWSGI_OPTION_LOG_BIG 13
#define UWSGI_OPTION_LOG_SENDFILE 14
#define UWSGI_OPTION_BACKLOG_STATUS 15
#define UWSGI_OPTION_BACKLOG_ERRORS 16
#define UWSGI_OPTION_SPOOLER_HARAKIRI 17
#define UWSGI_OPTION_MULE_HARAKIRI 18
#define UWSGI_OPTION_MAX_WORKER_LIFETIME 19
#define UWSGI_OPTION_MIN_WORKER_LIFETIME 20

#define UWSGI_SPOOLER_EXTERNAL 1

#define UWSGI_MODIFIER_ADMIN_REQUEST 10
#define UWSGI_MODIFIER_SPOOL_REQUEST 17
Expand All @@ -687,7 +689,7 @@ struct uwsgi_opt {
#define UWSGI_MODIFIER_MULTICAST 74
#define UWSGI_MODIFIER_PING 100

#define UWSGI_MODIFIER_RESPONSE 255
#define UWSGI_MODIFIER_RESPONSE 255

#define NL_SIZE 2
#define H_SEP_SIZE 2
Expand Down