bug fix for spooler

This commit is contained in:
roberto@fierobecco
2009-12-07 07:56:49 +01:00
parent 95b70423b0
commit ef4d3207d4
4 changed files with 91 additions and 25 deletions
+13 -4
View File
@@ -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'}
+18
View File
@@ -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) {
+54 -19
View File
@@ -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<numproc+master_process;i++) {
/* let the worker know his worker_id (wid) */
mywid = i;
pid = fork();
if (pid == 0 ) {
mypid = getpid();
@@ -1113,7 +1123,7 @@ int main(int argc, char *argv[], char *envp[]) {
else {
fprintf(stderr, "spawned uWSGI worker %d (pid: %d)\n", i, pid);
if (master_process)
workers[i] = pid ;
workers[i].pid = pid ;
gettimeofday(&last_respawn, NULL) ;
respawn_delta = last_respawn.tv_sec;
}
@@ -1167,13 +1177,28 @@ int main(int argc, char *argv[], char *envp[]) {
perror("execve()");
exit(1);
}
diedpid = waitpid(WAIT_ANY , &waitpid_status, 0) ;
diedpid = waitpid(WAIT_ANY , &waitpid_status, WNOHANG) ;
if (diedpid == -1) {
perror("waitpid()");
fprintf(stderr, "something horrible happened...\n");
reap_them_all();
exit(1);
}
else if (diedpid == 0) {
/* all processes ok, doing status scan after 1 second */
select(0, NULL, NULL, NULL, &check_interval);
for(i=1;i<=numproc;i++) {
/* first check for harakiri */
if (workers[i].harakiri > 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) {
+6 -2
View File
@@ -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);