mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 13:41:28 +00:00
the new spooler is working
This commit is contained in:
+441
-367
File diff suppressed because it is too large
Load Diff
+1313
-1300
File diff suppressed because it is too large
Load Diff
@@ -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 ***"
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user