the new spooler is working

This commit is contained in:
roberto@maverick64
2011-01-29 11:48:46 +01:00
parent 0a37852c5f
commit 9562c81590
5 changed files with 1916 additions and 1865 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+152 -197
View File
@@ -13,18 +13,28 @@ pid_t spooler_start() {
exit(1);
}
else if (pid == 0) {
for(i=0;i<uwsgi.sockets_cnt;i++) {
for (i = 0; i < uwsgi.sockets_cnt; i++) {
close(uwsgi.sockets[i].fd);
}
spooler();
}
else if (pid > 0) {
uwsgi_log( "spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid);
uwsgi_log("spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid);
}
return pid;
}
void destroy_spool(char *file) {
if (unlink(file)) {
uwsgi_error("unlink()");
uwsgi_log("something horrible happened to the spooler. Better to kill it.\n");
exit(1);
}
}
int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
@@ -32,15 +42,19 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
int fd;
struct uwsgi_header uh;
uwsgi_lock(uwsgi.spooler_lock);
gettimeofday(&tv, NULL);
if (snprintf(filename, 1024, "%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uwsgi.spool_dir, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) {
uwsgi_unlock(uwsgi.spooler_lock);
return 0;
}
fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
if (fd < 0) {
uwsgi_error("open()");
uwsgi_unlock(uwsgi.spooler_lock);
return 0;
}
@@ -48,40 +62,44 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
if (lockf(fd, F_LOCK, 0)) {
uwsgi_error("lockf()");
#else
if (flock(fd, LOCK_EX)) {
uwsgi_error("flock()");
if (flock(fd, LOCK_EX)) {
uwsgi_error("flock()");
#endif
close(fd);
return 0;
}
uh.modifier1 = 17;
uh.modifier2 = 0;
uh.pktsize = (uint16_t) size;
#ifdef __BIG_ENDIAN__
uh.pktsize = uwsgi_swap16(uh.pktsize);
#endif
if (write(fd, &uh, 4) != 4) {
goto clear;
}
if (write(fd, buffer, size) != size) {
goto clear;
}
close(fd);
uwsgi_log( "written %d bytes to spool file %s\n", size + 4, filename);
return 1;
clear:
uwsgi_error("write()");
unlink(filename);
close(fd);
uwsgi_unlock(uwsgi.spooler_lock);
return 0;
}
uh.modifier1 = 17;
uh.modifier2 = 0;
uh.pktsize = (uint16_t) size;
#ifdef __BIG_ENDIAN__
uh.pktsize = uwsgi_swap16(uh.pktsize);
#endif
if (write(fd, &uh, 4) != 4) {
goto clear;
}
if (write(fd, buffer, size) != size) {
goto clear;
}
close(fd);
uwsgi_log("written %d bytes to spool file %s\n", size + 4, filename);
uwsgi_unlock(uwsgi.spooler_lock);
return 1;
clear:
uwsgi_unlock(uwsgi.spooler_lock);
uwsgi_error("write()");
unlink(filename);
close(fd);
return 0;
}
@@ -89,20 +107,17 @@ clear:
void spooler() {
DIR *sdir;
struct dirent *dp;
int i, ret;
int spool_fd;
uint16_t uwstrlen;
int rlen = 0;
int datasize;
// prevent process blindly reading stdin to make mess
int nullfd;
struct uwsgi_header uh;
char *key;
char *val;
char spool_buf[0xffff];
if (chdir(uwsgi.spool_dir)) {
uwsgi_error("chdir()");
@@ -111,11 +126,11 @@ void spooler() {
// asked by Marco Beri
#ifdef __HAIKU__
uwsgi_log( "lowering spooler priority to %d\n", B_LOW_PRIORITY);
set_thread_priority(find_thread(NULL), B_LOW_PRIORITY);
uwsgi_log("lowering spooler priority to %d\n", B_LOW_PRIORITY);
set_thread_priority(find_thread(NULL), B_LOW_PRIORITY);
#else
uwsgi_log( "lowering spooler priority to %d\n", PRIO_MAX);
setpriority(PRIO_PROCESS, getpid(), PRIO_MAX);
uwsgi_log("lowering spooler priority to %d\n", PRIO_MAX);
setpriority(PRIO_PROCESS, getpid(), PRIO_MAX);
#endif
nullfd = open("/dev/null", O_RDONLY);
@@ -124,193 +139,133 @@ void spooler() {
exit(1);
}
if (nullfd != 0) {
dup2(nullfd, 0);
close(nullfd);
}
if (nullfd != 0) {
dup2(nullfd, 0);
close(nullfd);
}
for (;;) {
for (;;) {
sleep(uwsgi.shared->spooler_frequency);
sleep(uwsgi.shared->spooler_frequency);
sdir = opendir(uwsgi.spool_dir);
if (sdir) {
while ((dp = readdir(sdir)) != NULL) {
if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) {
struct stat sf_lstat;
if (lstat(dp->d_name, &sf_lstat)) {
sdir = opendir(uwsgi.spool_dir);
if (sdir) {
while ((dp = readdir(sdir)) != NULL) {
if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) {
struct stat sf_lstat;
if (lstat(dp->d_name, &sf_lstat)) {
continue;
}
if (!S_ISREG(sf_lstat.st_mode)) {
continue;
}
if (!access(dp->d_name, R_OK | W_OK)) {
uwsgi_log("managing spool request %s ...\n", dp->d_name);
spool_fd = open(dp->d_name, O_RDONLY);
if (spool_fd < 0) {
uwsgi_error("open()");
continue;
}
if (!S_ISREG(sf_lstat.st_mode)) {
continue;
}
if (!access(dp->d_name, R_OK | W_OK)) {
uwsgi_log( "managing spool request %s ...\n", dp->d_name);
spool_fd = open(dp->d_name, O_RDONLY);
if (spool_fd < 0) {
uwsgi_error("open()");
continue;
}
#ifdef __sun__
if (lockf(spool_fd, F_LOCK, 0)) {
uwsgi_error("lockf()");
if (lockf(spool_fd, F_LOCK, 0)) {
uwsgi_error("lockf()");
#else
if (flock(spool_fd, LOCK_EX)) {
uwsgi_error("flock()");
if (flock(spool_fd, LOCK_EX)) {
uwsgi_error("flock()");
#endif
close(spool_fd);
continue;
}
close(spool_fd);
continue;
}
if (read(spool_fd, &uh, 4) != 4) {
uwsgi_error("read()");
close(spool_fd);
continue;
}
if (read(spool_fd, &uh, 4) != 4) {
uwsgi_error("read()");
close(spool_fd);
continue;
}
#ifdef __BIG_ENDIAN__
uh.pktsize = uwsgi_swap16(uh.pktsize);
uh.pktsize = uwsgi_swap16(uh.pktsize);
#endif
datasize = 0;
while (datasize < uh.pktsize) {
rlen = read(spool_fd, &uwstrlen, 2);
if (rlen != 2) {
uwsgi_error("read()");
goto next_spool;
}
datasize += rlen;
key = NULL;
val = NULL;
if (uwstrlen > 0) {
key = malloc(uwstrlen + 1);
if (!key) {
uwsgi_error("malloc()");
goto retry_later;
}
rlen = read(spool_fd, key, uwstrlen);
if (rlen != uwstrlen) {
uwsgi_error("read()");
free(key);
goto next_spool;
}
datasize += rlen;
key[rlen] = 0;
if (read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
uwsgi_error("read()");
destroy_spool(dp->d_name);
close(spool_fd);
continue;
}
close(spool_fd);
rlen = read(spool_fd, &uwstrlen, 2);
if (rlen != 2) {
uwsgi_error("read()");
free(key);
goto next_spool;
}
datasize += rlen;
for(i=0;i<0xff;i++) {
if (uwsgi.p[i]->spooler) {
ret = uwsgi.p[i]->spooler(spool_buf, uh.pktsize);
if (ret == 0) continue;
if (ret == -2) {
if (uwstrlen > 0) {
val = malloc(uwstrlen + 1);
if (!val) {
free(key);
uwsgi_error("malloc()");
goto retry_later;
}
rlen = read(spool_fd, val, uwstrlen);
if (rlen != uwstrlen) {
uwsgi_error("read()");
free(key);
goto next_spool;
}
datasize += rlen;
val[rlen] = 0;
}
/*
if (PyDict_SetItemString(spool_env, key, PyString_FromStringAndSize(val, uwstrlen))) {
PyErr_Print();
free(key);
free(val);
goto retry_later;
}
*/
free(key);
free(val);
}
else {
break;
}
uwsgi_log("done with task/spool %s\n", dp->d_name);
destroy_spool(dp->d_name);
}
/*
pass request to plugins
*/
uwsgi_log( "done with task/spool %s\n", dp->d_name);
next_spool:
if (unlink(dp->d_name)) {
uwsgi_error("unlink");
uwsgi_log( "something horrible happened to the spooler. Better to kill it.\n");
exit(1);
}
retry_later:
close(spool_fd);
// re-spool it
break;
}
}
}
closedir(sdir);
}
else {
uwsgi_error("opendir()");
}
}
}
}
closedir(sdir);
}
else {
uwsgi_error("opendir()");
}
}
}
int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
int i;
char spool_filename[1024];
int i;
char spool_filename[1024];
if (uwsgi.spool_dir == NULL) {
uwsgi_log( "the spooler is inactive !!!...skip\n");
uwsgi_send_empty_pkt(wsgi_req->poll.fd, NULL, 255, 0);
return -1;
}
if (uwsgi.spool_dir == NULL) {
uwsgi_log("the spooler is inactive !!!...skip\n");
uwsgi_send_empty_pkt(wsgi_req->poll.fd, NULL, 255, 0);
return -1;
}
uwsgi_log( "managing spool request...\n");
i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->buffer, wsgi_req->uh.pktsize);
wsgi_req->uh.modifier1 = 255;
wsgi_req->uh.pktsize = 0;
if (i > 0) {
wsgi_req->uh.modifier2 = 1;
if (write(wsgi_req->poll.fd, wsgi_req, 4) != 4) {
uwsgi_log( "disconnected client, remove spool file.\n");
/* client disconnect, remove spool file */
if (unlink(spool_filename)) {
uwsgi_error("unlink()");
uwsgi_log( "something horrible happened !!! check your spooler ASAP !!!\n");
goodbye_cruel_world();
}
}
return 0;
uwsgi_log("managing spool request...\n");
i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize);
wsgi_req->uh.modifier1 = 255;
wsgi_req->uh.pktsize = 0;
if (i > 0) {
wsgi_req->uh.modifier2 = 1;
if (write(wsgi_req->poll.fd, wsgi_req, 4) != 4) {
uwsgi_log("disconnected client, remove spool file.\n");
/* client disconnect, remove spool file */
if (unlink(spool_filename)) {
uwsgi_error("unlink()");
uwsgi_log("something horrible happened !!! check your spooler ASAP !!!\n");
goodbye_cruel_world();
}
else {
/* announce a failed spool request */
wsgi_req->uh.modifier2 = 0;
i = write(wsgi_req->poll.fd, wsgi_req, 4);
if (i != 4) {
uwsgi_error("write()");
}
}
return -1;
}
return 0;
}
else {
/* announce a failed spool request */
wsgi_req->uh.modifier2 = 0;
i = write(wsgi_req->poll.fd, wsgi_req, 4);
if (i != 4) {
uwsgi_error("write()");
}
}
return -1;
}
#else
#warning "*** Spooler support is disabled ***"
+6
View File
@@ -1077,6 +1077,12 @@ int uwsgi_start(void *v_argv) {
uwsgi_lock_init(uwsgi.daemon_table_lock);
}
if (uwsgi.spool_dir) {
// spooler lock
uwsgi.spooler_lock = uwsgi_mmap_shared_lock();
uwsgi_lock_init(uwsgi.spooler_lock);
}
uwsgi.rpc_table_lock = uwsgi_mmap_shared_lock();
uwsgi_lock_init(uwsgi.rpc_table_lock);
+4 -1
View File
@@ -451,6 +451,8 @@ struct uwsgi_plugin {
char* (*decode_string)(void *);
int (*signal_handler)(uint8_t, void *, char *, uint8_t);
int (*spooler)(char *, uint16_t);
uint16_t (*rpc)(void *, uint8_t, char **, char *);
};
@@ -936,6 +938,7 @@ struct uwsgi_server {
void *fmon_table_lock;
void *timer_table_lock;
void *rpc_table_lock;
void *spooler_lock;
void *daemon_table_lock;
@@ -1148,7 +1151,7 @@ void snmp_init(void);
#endif
#ifdef UWSGI_SPOOLER
int spool_request(char *, int, char *, int);
int spool_request(char *, int, int, char *, int);
void spooler(void);
pid_t spooler_start(void);
#endif