diff --git a/testapp.py b/testapp.py index de8203c6..88c18d5d 100644 --- a/testapp.py +++ b/testapp.py @@ -10,11 +10,20 @@ def myspooler(env): uwsgi.spooler = myspooler +def helloworld(): + return 'Hello World' + +def increment(): + return "Shared counter is %d\n" % uwsgi.sharedarea_inclong(100) + +def force_harakiri(): + time.sleep(60) + + + def application(env, start_response): + start_response('200 OK', [('Content-Type', 'text/plain')]) - try: - yield "Shared counter is %d\n" % uwsgi.sharedarea_inclong(100) - except: - yield 'Hello World' + yield { '/': helloworld, '/sleep': force_harakiri, '/counter': increment }[env['PATH_INFO']]() applications = {'/':'application'} diff --git a/utils.c b/utils.c index d5705a98..fd544056 100644 --- a/utils.c +++ b/utils.c @@ -1,5 +1,23 @@ #include "uwsgi.h" +extern struct uwsgi_worker *workers; +extern int mywid ; + +void set_harakiri(int sec) { + if (workers) { + if (sec == 0) { + workers[mywid].harakiri = 0 ; + } + else { + workers[mywid].harakiri = time(NULL) + sec ; + fprintf(stderr,"harakiri set to %d\n", workers[mywid].harakiri); + } + } + else { + alarm(sec); + } +} + #ifndef UNBIT void daemonize(char *logfile) { diff --git a/uwsgi.c b/uwsgi.c index 6346ee34..d4084673 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -128,16 +128,19 @@ char *sharedarea ; void *sharedareamutex ; int sharedareasize ; -// save my pid for logging -pid_t mypid; // the list of workers -pid_t *workers; +struct uwsgi_worker *workers ; + +// save my pid for logging +pid_t mypid; +int mywid = 0 ; int find_worker_id(pid_t pid) { int i ; for(i = 1 ; i<= numproc ; i++) { - if (workers[i] == pid) + fprintf(stderr,"%d of %d\n", pid, workers[i].pid); + if (workers[i].pid == pid) return i ; } @@ -237,7 +240,7 @@ void kill_them_all() { int i ; fprintf(stderr,"SIGINT/SIGQUIT received...killing workers...\n"); for(i=1;i<=numproc;i++) { - kill(workers[i], SIGINT); + kill(workers[i].pid, SIGINT); } } @@ -245,7 +248,7 @@ void grace_them_all() { int i ; fprintf(stderr,"...gracefully killing workers...\n"); for(i=1;i<=numproc;i++) { - kill(workers[i], SIGHUP); + kill(workers[i].pid, SIGHUP); } } @@ -253,7 +256,7 @@ void reap_them_all() { int i ; fprintf(stderr,"...brutally killing workers...\n"); for(i=1;i<=numproc;i++) { - kill(workers[i], SIGTERM); + kill(workers[i].pid, SIGTERM); } } @@ -548,6 +551,7 @@ int memory_debug = 0 ; int main(int argc, char *argv[], char *envp[]) { + struct timeval check_interval = {.tv_sec = 1, .tv_usec = 0 }; #ifndef PYTHREE PyObject *uwsgi_module; @@ -1072,7 +1076,11 @@ int main(int argc, char *argv[], char *envp[]) { else { fprintf(stderr, "spawned uWSGI master process (pid: %d)\n", mypid); } - workers = malloc(sizeof(pid_t)*numproc+1); + workers = mmap(NULL, sizeof(struct uwsgi_worker)*numproc+1, PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANON , -1, 0); + if (!workers) { + perror("mmap()"); + exit(1); + } } #ifdef UNBIT @@ -1097,6 +1105,8 @@ int main(int argc, char *argv[], char *envp[]) { #endif for(i=1;i 0) { + if (workers[i].harakiri < time(NULL)) { + /* first try to invoke the harakiri() custom handler */ + /* the brutally kill the worker */ + kill(workers[i].pid, SIGKILL); + } + } + } + continue; + } #ifndef ROCK_SOLID /* reload the spooler */ if (spool_dir && spooler_pid > 0) { @@ -1203,6 +1228,7 @@ int main(int argc, char *argv[], char *envp[]) { } gettimeofday(&last_respawn, NULL) ; respawn_delta = last_respawn.tv_sec; + mywid = find_worker_id(diedpid); pid = fork(); if (pid == 0 ) { mypid = getpid(); @@ -1213,9 +1239,13 @@ int main(int argc, char *argv[], char *envp[]) { } else { fprintf(stderr, "Respawned uWSGI worker (new pid: %d)\n", pid); - i = find_worker_id(diedpid); - if (i > 0) { - workers[i] = pid ; + if (mywid > 0) { + workers[mywid].pid = pid ; + workers[mywid].harakiri = 0 ; + workers[mywid].requests = 0 ; + workers[mywid].failed_requests = 0 ; + workers[mywid].respawn_count++ ; + workers[mywid].last_spawn = time(NULL) ; } else { fprintf(stderr, "warning the died pid was not in the workers list. Probably you hit a BUG of uWSGI\n") ; @@ -1238,7 +1268,7 @@ int main(int argc, char *argv[], char *envp[]) { exit(1); } - if (harakiri_timeout > 0) { + if (harakiri_timeout > 0 && workers == NULL) { signal(SIGALRM, (void *) &harakiri); } @@ -1571,16 +1601,16 @@ int main(int argc, char *argv[], char *envp[]) { if (wsgi_req.modifier != 0) { switch(wsgi_req.modifier) { case UWSGI_MODIFIER_HT_S: - alarm(wsgi_req.modifier_arg); + set_harakiri(wsgi_req.modifier_arg); case UWSGI_MODIFIER_HT_M: - alarm(wsgi_req.modifier_arg*60); + set_harakiri(wsgi_req.modifier_arg*60); case UWSGI_MODIFIER_HT_H: - alarm(wsgi_req.modifier_arg*3600); + set_harakiri(wsgi_req.modifier_arg*3600); } } else { #endif - alarm(harakiri_timeout); + set_harakiri(harakiri_timeout); #ifdef UNBIT } #endif @@ -1744,7 +1774,7 @@ int main(int argc, char *argv[], char *envp[]) { #endif PyErr_Clear(); if (harakiri_timeout > 0) { - alarm(0); + set_harakiri(0); } #ifndef ROCK_SOLID if (single_interpreter == 0) { @@ -1986,6 +2016,11 @@ int init_uwsgi_app(PyObject *force_wsgi_dict, PyObject *my_callable) { wsgi_req.script_name = (char *) app_slash ; id = 0 ; } + else if (wsgi_req.script_name_len == 1) { + if (wsgi_req.script_name[0] == '/') { + id = 0 ; + } + } zero = PyString_FromStringAndSize(wsgi_req.script_name, wsgi_req.script_name_len); if (!zero) { diff --git a/uwsgi.h b/uwsgi.h index c5e28b0b..11b55e3e 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -77,11 +77,13 @@ struct __attribute__((packed)) uwsgi_worker { + pid_t pid; + time_t last_spawn; unsigned long long requests; unsigned long long failed_requests; time_t harakiri; - unsigned long long respawn; -} + unsigned long long respawn_count; +}; struct __attribute__((packed)) wsgi_request { unsigned char modifier; @@ -191,3 +193,5 @@ int spool_request(char *, char *, char *, char *, int, char *, int); void spooler(char *, PyObject *); pid_t spooler_start(char *,int, PyObject *); #endif + +void set_harakiri(int);