Compare commits

..
1 Commits
Author SHA1 Message Date
Unbit 41bc23bb40 backports from 1.9.19 2013-10-16 20:58:20 +02:00
67 changed files with 569 additions and 3366 deletions
+3 -5
View File
@@ -1,10 +1,8 @@
PYTHON := python
all:
$(PYTHON) uwsgiconfig.py --build $(PROFILE)
python uwsgiconfig.py --build
clean:
$(PYTHON) uwsgiconfig.py --clean
python uwsgiconfig.py --clean
check:
$(PYTHON) uwsgiconfig.py --check
python uwsgiconfig.py --check
+1 -1
View File
@@ -17,7 +17,7 @@ plugins =
bin_name = uwsgi
append_version =
plugin_dir = .
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash, router_expires, router_metrics, transformation_template, stats_pusher_socket
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash, router_expires
as_shared_library = false
locking = auto
+2 -2
View File
@@ -1,4 +1,4 @@
[uwsgi]
# pypy,go
main_plugin = erlang,psgi,rack,lua,python,gevent,php,cgi,pyerl,glusterfs,pty,xslt,msgpack,geoip,v8,pam,ldap,mono,jvm,ring,jwsgi
# pypy,jvm,ring,jwsgi
main_plugin = erlang,psgi,rack,lua,python,gevent,php,cgi,mono,pyerl,go
inherit = base
+17 -22
View File
@@ -308,42 +308,29 @@ end:
async_reset_request(uwsgi.wsgi_req);
uwsgi_close_request(uwsgi.wsgi_req);
uwsgi.wsgi_req->async_status = UWSGI_OK;
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
}
void async_schedule_to_req_green(void) {
struct wsgi_request *wsgi_req = uwsgi.wsgi_req;
#ifdef UWSGI_ROUTING
if (uwsgi_apply_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
if (uwsgi_apply_routes(uwsgi.wsgi_req) == UWSGI_ROUTE_BREAK) {
goto end;
}
#endif
for(;;) {
if (uwsgi.p[wsgi_req->uh->modifier1]->request(wsgi_req) <= UWSGI_OK) {
if (uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req) <= UWSGI_OK) {
break;
}
wsgi_req->switches++;
if (uwsgi.schedule_fix) {
uwsgi.schedule_fix(wsgi_req);
}
uwsgi.wsgi_req->switches++;
// switch after each yield
uwsgi.schedule_to_main(wsgi_req);
uwsgi.schedule_to_main(uwsgi.wsgi_req);
}
#ifdef UWSGI_ROUTING
end:
#endif
// re-set the global state
uwsgi.wsgi_req = wsgi_req;
async_reset_request(wsgi_req);
uwsgi_close_request(wsgi_req);
// re-set the global state (routing could have changed it)
uwsgi.wsgi_req = wsgi_req;
wsgi_req->async_status = UWSGI_OK;
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req;
async_reset_request(uwsgi.wsgi_req);
uwsgi_close_request(uwsgi.wsgi_req);
uwsgi.wsgi_req->async_status = UWSGI_OK;
}
void async_loop() {
@@ -524,11 +511,19 @@ void async_loop() {
uwsgi.wsgi_req->switches++;
// request ended ?
if (uwsgi.wsgi_req->async_status <= UWSGI_OK ||
uwsgi.wsgi_req->waiting_fds || uwsgi.wsgi_req->async_timeout) {
if (uwsgi.wsgi_req->async_status <= UWSGI_OK) {
// remove from the runqueue
runqueue_remove(current_request);
// push wsgi_request in the unused stack
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
}
else if (uwsgi.wsgi_req->waiting_fds || uwsgi.wsgi_req->async_timeout) {
// remove this request from the runqueue
runqueue_remove(current_request);
}
current_request = next_request;
}
-13
View File
@@ -204,19 +204,6 @@ int uwsgi_buffer_u64be(struct uwsgi_buffer *ub, uint64_t num) {
return uwsgi_buffer_append(ub, (char *) buf, 8);
}
int uwsgi_buffer_u64le(struct uwsgi_buffer *ub, uint64_t num) {
uint8_t buf[8];
buf[0] = (uint8_t) (num & 0xff);
buf[1] = (uint8_t) ((num >> 8) & 0xff);
buf[2] = (uint8_t) ((num >> 16) & 0xff);
buf[3] = (uint8_t) ((num >> 24) & 0xff);
buf[4] = (uint8_t) ((num >> 32) & 0xff);
buf[5] = (uint8_t) ((num >> 40) & 0xff);
buf[6] = (uint8_t) ((num >> 48) & 0xff);
buf[7] = (uint8_t) ((num >> 56) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 8);
}
int uwsgi_buffer_f64be(struct uwsgi_buffer *ub, double num) {
uint8_t buf[8];
-4
View File
@@ -493,10 +493,6 @@ add:
if (op->flags & UWSGI_OPT_MIME) {
uwsgi.build_mime_dict = 1;
}
// enable metrics ?
if (op->flags & UWSGI_OPT_METRICS) {
uwsgi.has_metrics = 1;
}
// immediate ?
if (op->flags & UWSGI_OPT_IMMEDIATE) {
op->func(key, value, op->data);
+3 -5
View File
@@ -233,7 +233,7 @@ void uwsgi_detach_daemons() {
#endif
uwsgi_log("[uwsgi-daemons] stopping daemon (pid: %d): %s\n", (int) ud->pid, ud->command);
// try to gracefully stop daemon, kill it if it won't die
// if mercy is not set then wait up to 3 seconds
// if mercy is not set than wait up to 3 seconds
time_t timeout = uwsgi_now() + (uwsgi.reload_mercy ? uwsgi.reload_mercy : 3);
int waitpid_status;
while (!kill(ud->pid, 0)) {
@@ -241,7 +241,7 @@ void uwsgi_detach_daemons() {
sleep(1);
waitpid(-ud->pid, &waitpid_status, WNOHANG);
if (uwsgi_now() >= timeout) {
uwsgi_log("[uwsgi-daemons] daemon did not die in time, killing (pid: %d): %s\n", (int) ud->pid, ud->command);
uwsgi_log("[uwsgi-daemons] daemon did not died in time, killing (pid: %d): %s\n", (int) ud->pid, ud->command);
kill(-ud->pid, SIGKILL);
break;
}
@@ -263,8 +263,6 @@ void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {
if (uwsgi.current_time - ud->last_spawn <= 3) {
throttle = ud->respawns - (uwsgi.current_time - ud->last_spawn);
// if ud->respawns == 0 then we can end up with throttle < 0
if (throttle <= 0) throttle = 1;
}
pid_t pid = uwsgi_fork("uWSGI external daemon");
@@ -325,7 +323,7 @@ void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {
if (throttle) {
uwsgi_log("[uwsgi-daemons] throttling \"%s\" for %d seconds\n", ud->command, throttle);
sleep((unsigned int) throttle);
sleep(throttle);
}
uwsgi_log("[uwsgi-daemons] %sspawning \"%s\"\n", ud->respawns > 0 ? "re" : "", ud->command);
-9
View File
@@ -974,7 +974,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
#endif
#ifdef UWSGI_CAP
#if defined(CAP_LAST_CAP) && defined(PR_CAPBSET_READ) && defined(PR_CAPBSET_DROP)
if (uwsgi.emperor_cap && uwsgi.emperor_cap_count > 0) {
int i;
for(i=0;i<=CAP_LAST_CAP;i++) {
@@ -1011,7 +1010,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
uwsgi_log("capabilities applied for vassal %s (pid: %d)\n", n_ui->name, (int) getpid());
}
#endif
#endif
#endif
if (uwsgi.emperor_tyrant) {
@@ -1102,7 +1100,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
struct uwsgi_string_list *uct;
uwsgi_foreach(uct, uwsgi.vassals_templates_before) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_includes_before) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_set) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_templates) counter += 2;
uwsgi_foreach(uct, uwsgi.vassals_includes) counter += 2;
@@ -1125,12 +1122,6 @@ static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
counter += 2;
}
uwsgi_foreach (uct, uwsgi.vassals_set) {
vassal_argv[counter] = "--set";
vassal_argv[counter + 1] = uct->value;
counter += 2;
}
char *colon = NULL;
if (uwsgi.emperor_broodlord) {
colon = strchr(n_ui->name, ':');
+1 -1
View File
@@ -99,7 +99,7 @@ int uwsgi_master_fifo() {
}
int uwsgi_master_fifo_manage(int fd) {
unsigned char cmd;
char cmd;
ssize_t rlen = read(fd, &cmd, 1);
if (rlen < 0) {
if (uwsgi_is_again()) return 0;
-1
View File
@@ -38,7 +38,6 @@ void uwsgi_fsmon_setup() {
char *space = strchr(copy, ' ');
if (!space) {
uwsgi_log("[uwsgi-fsmon] invalid syntax: \"%s\"\n", usl->value);
free(copy);
goto next;
}
*space = 0;
+1 -21
View File
@@ -17,7 +17,7 @@ uint32_t djb33x_hash(char *key, uint64_t keylen) {
// Murmur2 hash Copyright (C) Austin Appleby
// adapted from nginx
static uint32_t murmur2_hash(char *key, uint64_t keylen) {
uint32_t murmur2_hash(char *key, uint64_t keylen) {
uint32_t h, k;
uint8_t *ukey = (uint8_t *) key;
@@ -56,23 +56,6 @@ static uint32_t murmur2_hash(char *key, uint64_t keylen) {
return h;
}
static uint32_t random_hash(char *key, uint64_t keylen) {
return (uint32_t) rand();
}
/*
not atomic, avoid its use in multithreaded modes
*/
static uint32_t rr_hash(char *key, uint64_t keylen) {
static uint32_t rr = 0;
uint32_t max_value = uwsgi_str_num(key, keylen);
uint32_t ret = rr;
rr++;
if (rr > max_value) {
rr = 0;
}
return ret;
}
struct uwsgi_hash_algo *uwsgi_hash_algo_get(char *name) {
struct uwsgi_hash_algo *uha = uwsgi.hash_algos;
@@ -107,7 +90,4 @@ void uwsgi_hash_algo_register(char *name, uint32_t (*func)(char *, uint64_t)) {
void uwsgi_hash_algo_register_all() {
uwsgi_hash_algo_register("djb33x", djb33x_hash);
uwsgi_hash_algo_register("murmur2", murmur2_hash);
uwsgi_hash_algo_register("random", random_hash);
uwsgi_hash_algo_register("rand", random_hash);
uwsgi_hash_algo_register("rr", rr_hash);
}
-1
View File
@@ -51,7 +51,6 @@ struct http_status_codes hsc[] = {
{"503", "Service Unavailable"},
{"504", "Gateway Timeout"},
{"505", "HTTP Version Not Supported"},
{"509", "Bandwidth Limit Exceeded"},
{"", NULL},
};
+2 -3
View File
@@ -270,7 +270,7 @@ static char *uwsgi_scheme_emperor(char *url, size_t *size, int add_zero) {
}
rlen = read(uwsgi.emperor_fd_config, ptr, remains);
if (rlen <= 0) {
uwsgi_log("[uwsgi-vassal] error reading config header from %s !!!\n", url);
uwsgi_log("[uwsgi-vassal] error reading config header from !!!\n", url);
exit(1);
}
ptr+=rlen;
@@ -293,7 +293,7 @@ static char *uwsgi_scheme_emperor(char *url, size_t *size, int add_zero) {
}
rlen = read(uwsgi.emperor_fd_config, ptr, remains);
if (rlen <= 0) {
uwsgi_log("[uwsgi-vassal] error reading config from %s !!!\n", url);
uwsgi_log("[uwsgi-vassal] error reading config from !!!\n", url);
exit(1);
}
ptr+=rlen;
@@ -364,7 +364,6 @@ static char *uwsgi_scheme_data(char *url, size_t *size, int add_zero) {
}
}
}
close(fd);
return buffer;
}
+2 -14
View File
@@ -498,7 +498,7 @@ void uwsgi_check_logrotate(void) {
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
}
if (uwsgi.log_maxsize > 0 && (uint64_t) uwsgi.shared->logsize > uwsgi.log_maxsize) {
if (uwsgi.log_maxsize > 0 && uwsgi.shared->logsize > uwsgi.log_maxsize) {
need_rotation = 1;
}
@@ -980,12 +980,6 @@ void uwsgi_logit_lf(struct wsgi_request *wsgi_req) {
uwsgi.logvectors[wsgi_req->async_id][pos].iov_len = 0;
}
}
// metric
else if (logchunk->type == 4) {
int64_t metric = uwsgi_metric_get(logchunk->ptr, NULL);
uwsgi.logvectors[wsgi_req->async_id][pos].iov_base = uwsgi_64bit2str(metric);
uwsgi.logvectors[wsgi_req->async_id][pos].iov_len = strlen(uwsgi.logvectors[wsgi_req->async_id][pos].iov_base);
}
if (uwsgi.logvectors[wsgi_req->async_id][pos].iov_len == 0 && logchunk->type != 0) {
uwsgi.logvectors[wsgi_req->async_id][pos].iov_base = (char *) empty_var;
@@ -1237,7 +1231,6 @@ void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
1 -> offsetof variable
2 -> logvar
3 -> func
4 -> metric
*/
logchunk->type = variable;
@@ -1404,11 +1397,6 @@ void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
logchunk->func = uwsgi_lf_headers;
logchunk->free = 1;
}
else if (!uwsgi_starts_with(ptr, len, "metric.", 7)) {
logchunk->type = 4;
logchunk->ptr = uwsgi_concat2n(ptr+7, len - 7, "", 0);
logchunk->free = 1;
}
// logvar
else {
logchunk->type = 2;
@@ -1853,7 +1841,7 @@ void uwsgi_log_encoder_parse_vars(struct uwsgi_log_encoder *ule) {
/*
// format: foo ${var} bar
msg (the logline)
msgnl (the logline with newline)
msgnl (the logine with newline)
unix (the time_t value)
micros (current microseconds)
strftime (strftime)
+17 -52
View File
@@ -2,32 +2,6 @@
extern struct uwsgi_server uwsgi;
void uwsgi_update_load_counters() {
int i;
uint64_t busy_workers = 0;
uint64_t idle_workers = 0;
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
if (uwsgi_worker_is_busy(i) == 0) {
idle_workers++;
}
else {
busy_workers++;
}
}
}
if (busy_workers >= (uint64_t) uwsgi.numproc) {
ushared->overloaded++;
}
ushared->busy_workers = busy_workers;
ushared->idle_workers = idle_workers;
}
void uwsgi_restore_auto_snapshot(int signum) {
if (uwsgi.workers[1].snapshot > 0) {
@@ -58,25 +32,24 @@ void uwsgi_unblock_signal(int signum) {
}
void uwsgi_master_manage_udp(int udp_fd) {
char buf[4096];
struct sockaddr_in udp_client;
char udp_client_addr[16];
int i;
socklen_t udp_len = sizeof(udp_client);
ssize_t rlen = recvfrom(udp_fd, buf, 4096, 0, (struct sockaddr *) &udp_client, &udp_len);
ssize_t rlen = recvfrom(udp_fd, uwsgi.wsgi_req->buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len);
if (rlen < 0) {
uwsgi_error("uwsgi_master_manage_udp()/recvfrom()");
uwsgi_error("recvfrom()");
}
else if (rlen > 0) {
memset(udp_client_addr, 0, 16);
if (inet_ntop(AF_INET, &udp_client.sin_addr.s_addr, udp_client_addr, 16)) {
if (buf[0] == UWSGI_MODIFIER_MULTICAST_ANNOUNCE) {
if (uwsgi.wsgi_req->buffer[0] == UWSGI_MODIFIER_MULTICAST_ANNOUNCE) {
}
else if (buf[0] == 0x30 && uwsgi.snmp) {
manage_snmp(udp_fd, (uint8_t *) buf, rlen, &udp_client);
else if (uwsgi.wsgi_req->buffer[0] == 0x30 && uwsgi.snmp) {
manage_snmp(udp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client);
}
else {
@@ -84,7 +57,7 @@ void uwsgi_master_manage_udp(int udp_fd) {
int udp_managed = 0;
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->manage_udp) {
if (uwsgi.p[i]->manage_udp(udp_client_addr, udp_client.sin_port, buf, rlen)) {
if (uwsgi.p[i]->manage_udp(udp_client_addr, udp_client.sin_port, uwsgi.wsgi_req->buffer, rlen)) {
udp_managed = 1;
break;
}
@@ -93,12 +66,12 @@ void uwsgi_master_manage_udp(int udp_fd) {
// else a simple udp logger
if (!udp_managed) {
uwsgi_log("[udp:%s:%d] %.*s", udp_client_addr, ntohs(udp_client.sin_port), (int) rlen, buf);
uwsgi_log("[udp:%s:%d] %.*s", udp_client_addr, ntohs(udp_client.sin_port), (int) rlen, uwsgi.wsgi_req->buffer);
}
}
}
else {
uwsgi_error("uwsgi_master_manage_udp()/inet_ntop()");
uwsgi_error("inet_ntop()");
}
}
@@ -373,7 +346,6 @@ int master_loop(char **argv, char **environ) {
#ifdef UWSGI_SSL
uwsgi_start_legions();
#endif
uwsgi_metrics_start_collector();
uwsgi_add_reload_fds();
@@ -611,10 +583,8 @@ int master_loop(char **argv, char **environ) {
/* all processes ok, doing status scan after N seconds */
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval) {
if (!check_interval)
check_interval = 1;
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = 1;
}
// add unregistered file monitors
@@ -649,14 +619,14 @@ int master_loop(char **argv, char **environ) {
if (ushared->rb_timers_cnt > 0) {
min_timeout = uwsgi_min_rb_timer(rb_timers, NULL);
if (min_timeout) {
int delta = min_timeout->value - uwsgi_now();
if (delta <= 0) {
if (min_timeout == NULL) {
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
}
else {
check_interval = min_timeout->value - uwsgi_now();
if (check_interval <= 0) {
expire_rb_timeouts(rb_timers);
}
// if the timer expires before the check_interval, override it
else if (delta < check_interval) {
check_interval = delta;
check_interval = 0;
}
}
}
@@ -670,9 +640,6 @@ int master_loop(char **argv, char **environ) {
}
}
// update load counter
uwsgi_update_load_counters();
// check uwsgi-cron table
if (ushared->cron_cnt) {
@@ -713,10 +680,8 @@ int master_loop(char **argv, char **environ) {
uwsgi_master_check_idle();
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval) {
if (!check_interval)
check_interval = 1;
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = 1;
}
// get listen_queue status
-59
View File
@@ -871,65 +871,6 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
goto end;
}
if (uwsgi.has_metrics) {
if (uwsgi_stats_key(us, "metrics"))
goto end;
if (uwsgi_stats_object_open(us))
goto end;
uwsgi_rlock(uwsgi.metrics_lock);
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
int64_t um_val = *um->value;
if (uwsgi_stats_key(us, um->name)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_object_open(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_keylong(us, "type", (long long) um->type)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_comma(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_keyslong(us, "value", (long long) um_val)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
if (uwsgi_stats_object_close(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
um = um->next;
if (um) {
if (uwsgi_stats_comma(us)) {
uwsgi_rwunlock(uwsgi.metrics_lock);
goto end;
}
}
}
uwsgi_rwunlock(uwsgi.metrics_lock);
if (uwsgi_stats_object_close(us))
goto end;
if (uwsgi_stats_comma(us))
goto end;
}
if (uwsgi_stats_key(us, "sockets"))
goto end;
+54 -904
View File
File diff suppressed because it is too large Load Diff
+3 -13
View File
@@ -640,6 +640,7 @@ static int uwsgi_router_fixcl(struct uwsgi_route *ur, char *arg) {
return 0;
}
// log route
static int uwsgi_router_log_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
@@ -1198,21 +1199,10 @@ static int uwsgi_router_alarm(struct uwsgi_route *ur, char *arg) {
// send route
static int uwsgi_router_send_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
char **subject = (char **) (((char *)(wsgi_req))+route->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+route->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, route, *subject, *subject_len, route->data, route->data_len);
if (!ub) {
return UWSGI_ROUTE_BREAK;
}
uwsgi_response_write_body_do(wsgi_req, route->data, route->data_len);
if (route->custom) {
if (uwsgi_buffer_append(ub, "\r\n", 2)) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
uwsgi_response_write_body_do(wsgi_req, "\r\n", 2);
}
uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_send(struct uwsgi_route *ur, char *arg) {
-2
View File
@@ -301,10 +301,8 @@ int uwsgi_signal_send(int fd, uint8_t sig) {
else {
uwsgi_error("uwsgi_signal_send()");
}
uwsgi.shared->unrouted_signals++;
return -1;
}
uwsgi.shared->routed_signals++;
return 0;
}
+14 -55
View File
@@ -23,7 +23,6 @@ static uint64_t get_uwsgi_custom_snmp_value(uint64_t, uint8_t *);
static uint8_t snmp_int_to_snmp(uint64_t, uint8_t, uint8_t *);
static ssize_t build_snmp_response(uint8_t, uint8_t, uint8_t *, int, uint8_t *, uint8_t *, uint8_t *);
static ssize_t build_snmp_metric_response(int64_t, uint8_t, uint8_t *, int, uint8_t *, uint8_t *, uint8_t *);
void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_addr) {
@@ -72,7 +71,7 @@ void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_
uwsgi_debug("SNMP version: %d\n", version);
#endif
// check for community string (this must be set from the api using uwsgi.snmp_community or with --snmp-community arg)
// check for community string (this must be set from the python vm using uwsgi.snmp_community or with --snmp-community arg)
if (*ptr != SNMP_STRING)
return;
ptr++;
@@ -197,7 +196,7 @@ void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_
ptr++;
oidlen = *ptr;
if (oidlen < 11)
if (oidlen != 11)
return;
ptr++;
@@ -209,33 +208,21 @@ void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_
oid_part[0] = *ptr;
// old style SNMP metrics
if (oid_part[0] == 1 || oid_part[0] == 2) {
ptr++;
if (oid_part[0] != 1 && oid_part[0] != 2)
return;
ptr++;
oid_part[1] = *ptr;
if (oid_part[1] < 1 || oid_part[1] > 100)
return;
ptr++;
oid_part[1] = *ptr;
if (oid_part[1] < 1 || oid_part[1] > 100)
return;
ptr++;
// check for null
if (memcmp((char *) ptr, "\x05\x00", 2))
return;
ptr += 2;
size = build_snmp_response(oid_part[0], oid_part[1], buffer, size, seq1, seq2, seq3);
}
// metrics subsystem
else {
size_t metric_asn_len = oidlen - 9;
char *metric_asn = (char *) ptr;
struct uwsgi_metric *um = uwsgi_metric_find_by_asn(metric_asn, metric_asn_len);
if (!um) return;
uwsgi_rlock(uwsgi.metrics_lock);
int64_t value = *um->value;
uwsgi_rwunlock(uwsgi.metrics_lock);
size = build_snmp_metric_response(value, um->type, buffer, size, seq1, seq2, seq3);
}
// check for null
if (memcmp((char *) ptr, "\x05\x00", 2))
return;
ptr += 2;
size = build_snmp_response(oid_part[0], oid_part[1], buffer, size, seq1, seq2, seq3);
if (size > 0) {
if (sendto(fd, buffer, size, 0, (struct sockaddr *) client_addr, sizeof(struct sockaddr_in)) < 0) {
@@ -305,7 +292,6 @@ static uint8_t snmp_int_to_snmp(uint64_t snmp_val, uint8_t oid_type, uint8_t * b
uint8_t tlen;
int i, j;
uint8_t *ptr = (uint8_t *) & snmp_val;
int32_t val32 = (int32_t) snmp_val;
// check for counter, counter64 or gauge
@@ -317,7 +303,6 @@ static uint8_t snmp_int_to_snmp(uint64_t snmp_val, uint8_t oid_type, uint8_t * b
}
else {
tlen = 4;
ptr = (uint8_t *) &val32;
}
buffer[0] = tlen;
@@ -367,32 +352,6 @@ static ssize_t build_snmp_response(uint8_t oid1, uint8_t oid2, uint8_t * buffer,
}
static ssize_t build_snmp_metric_response(int64_t value, uint8_t type, uint8_t * buffer, int size, uint8_t * seq1, uint8_t * seq2, uint8_t * seq3) {
uint8_t oid_sz;
if (type == UWSGI_METRIC_GAUGE) {
buffer[size - 2] = SNMP_GAUGE;
oid_sz = snmp_int_to_snmp(value, SNMP_GAUGE, buffer + (size - 1));
}
else {
buffer[size - 2] = SNMP_COUNTER64;
oid_sz = snmp_int_to_snmp(value, SNMP_COUNTER64, buffer + (size - 1));
}
if (oid_sz < 1)
return -1;
oid_sz--;
buffer[1] += oid_sz;
*seq1 += oid_sz;
*seq2 += oid_sz;
*seq3 += oid_sz;
return size + oid_sz;
}
void uwsgi_opt_snmp(char *opt, char *value, void *foobar) {
uwsgi.snmp = 1;
if (value) {
+3 -19
View File
@@ -1366,7 +1366,7 @@ void uwsgi_add_sockets_to_queue(int queue, int async_id) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->fd_threads && async_id > -1 && uwsgi_sock->fd_threads[async_id] > -1) {
if (uwsgi_sock->fd_threads && async_id > -1) {
event_queue_add_fd_read(queue, uwsgi_sock->fd_threads[async_id]);
}
else if (uwsgi_sock->fd > -1) {
@@ -1910,7 +1910,7 @@ setup_proto:
uwsgi_sock->proto_close = uwsgi_proto_fastcgi_close;
}
else if (requested_protocol && !strcmp("scgi", requested_protocol)) {
else if (requested_protocol && (!strcmp("scgi", requested_protocol) || !strcmp("scgi", requested_protocol))) {
uwsgi_sock->proto = uwsgi_proto_scgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_cgi_prepare_headers;
@@ -1923,7 +1923,7 @@ setup_proto:
uwsgi_sock->proto_close = uwsgi_proto_base_close;
}
else if (requested_protocol && !strcmp("scgi-nph", requested_protocol)) {
else if (requested_protocol && (!strcmp("scgi-nph", requested_protocol) || !strcmp("scgi-nph", requested_protocol))) {
uwsgi_sock->proto = uwsgi_proto_scgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
@@ -1942,22 +1942,6 @@ setup_proto:
uwsgi.zeromq = 1;
}
#endif
else if (requested_protocol && !strcmp("puwsgi", requested_protocol)) {
uwsgi_sock->proto = uwsgi_proto_puwsgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_puwsgi_accept;
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
uwsgi_sock->proto_read_body = uwsgi_proto_noop_read_body;
uwsgi_sock->proto_write = uwsgi_proto_base_write;
uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
uwsgi_sock->proto_close = uwsgi_proto_puwsgi_close;
uwsgi_sock->fd_threads = uwsgi_malloc(sizeof(int) * uwsgi.cores);
memset(uwsgi_sock->fd_threads, -1, sizeof(int) * uwsgi.cores);
uwsgi_sock->retry = uwsgi_calloc(sizeof(int) * uwsgi.cores);
uwsgi.is_et = 1;
}
else {
uwsgi_sock->proto = uwsgi_proto_uwsgi_parser;
uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
+45 -18
View File
@@ -440,11 +440,6 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
void *events = event_queue_alloc(1);
for (;;) {
int nevents = event_queue_wait_multi(ut->queue, 1, events, 1);
if (nevents < 0) {
if (errno == EINTR) continue;
uwsgi_log_verbose("ending the stats pusher thread...\n");
return;
}
if (nevents > 0) {
int interesting_fd = event_queue_interesting_fd(events, 0);
char buf[4096];
@@ -462,8 +457,7 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
struct uwsgi_stats *us = NULL;
while (uspi) {
int delta = uspi->freq ? uspi->freq : uwsgi.stats_pusher_default_freq;
if (((uspi->last_run + delta) <= now) || (uspi->needs_retry && (uspi->next_retry <= now))) {
if (uspi->needs_retry) uspi->retries++;
if ((uspi->last_run + delta) <= now) {
if (uspi->raw) {
uspi->pusher->func(uspi, now, NULL, 0);
}
@@ -476,17 +470,6 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
uspi->pusher->func(uspi, now, us->base, us->pos);
}
uspi->last_run = now;
if (uspi->needs_retry && uspi->max_retries > 0 && uspi->retries < uspi->max_retries) {
uwsgi_log("[uwsgi-stats-pusher] %s failed (%d), retry in %ds\n", uspi->pusher->name, uspi->retries, uspi->retry_delay);
uspi->next_retry = now + uspi->retry_delay;
} else if (uspi->needs_retry && uspi->retries >= uspi->max_retries) {
uwsgi_log("[uwsgi-stats-pusher] %s failed and maximum number of retries was reached (%d)\n", uspi->pusher->name, uspi->retries);
uspi->needs_retry = 0;
uspi->retries = 0;
} else if (uspi->retries) {
uwsgi_log("[uwsgi-stats-pusher] retry succeeded for %s\n", uspi->pusher->name);
uspi->retries = 0;
}
}
next:
uspi = uspi->next;
@@ -548,6 +531,50 @@ struct uwsgi_stats_pusher *uwsgi_register_stats_pusher(char *name, void (*func)
return pusher;
}
struct uwsgi_stats_pusher_file_conf {
char *path;
char *freq;
char *separator;
};
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
struct uwsgi_stats_pusher_file_conf *uspic = (struct uwsgi_stats_pusher_file_conf *) uspi->data;
if (!uspi->configured) {
uspic = uwsgi_calloc(sizeof(struct uwsgi_stats_pusher_file_conf));
if (uspi->arg) {
if (uwsgi_kvlist_parse(uspi->arg, strlen(uspi->arg), ',', '=', "path", &uspic->path, "separator", &uspic->separator, "freq", &uspic->freq, NULL)) {
free(uspi);
return;
}
}
if (!uspic->path)
uspic->path = "uwsgi.stats";
if (!uspic->separator)
uspic->separator = "\n\n";
if (uspic->freq)
uspi->freq = atoi(uspic->freq);
uspi->configured = 1;
uspi->data = uspic;
}
int fd = open(uspic->path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
if (fd < 0) {
uwsgi_error_open(uspic->path);
return;
}
ssize_t rlen = write(fd, json, json_len);
if (rlen != (ssize_t) json_len) {
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
}
rlen = write(fd, uspic->separator, strlen(uspic->separator));
if (rlen != (ssize_t) strlen(uspic->separator)) {
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
}
close(fd);
}
static void stats_dump_var(char *k, uint16_t kl, char *v, uint16_t vl, void *data) {
struct uwsgi_stats *us = (struct uwsgi_stats *) data;
if (us->dirty) return;
+62 -201
View File
@@ -2,6 +2,7 @@
extern struct uwsgi_server uwsgi;
extern char **environ;
#ifdef __BIG_ENDIAN__
uint16_t uwsgi_swap16(uint16_t x) {
@@ -206,19 +207,17 @@ void uwsgi_set_cgroup() {
if (!uwsgi.cgroup)
return;
if (getuid()) return;
usl = uwsgi.cgroup;
while (usl) {
int mode = strtol(uwsgi.cgroup_dir_mode, 0, 8);
if (mkdir(usl->value, mode)) {
if (errno != EEXIST) {
uwsgi_error("uwsgi_set_cgroup()/mkdir()");
uwsgi_error("mkdir()");
exit(1);
}
if (chmod(usl->value, mode)) {
uwsgi_error("uwsgi_set_cgroup()/chmod()");
uwsgi_error("chmod()");
exit(1);
}
uwsgi_log("using Linux cgroup %s with mode %o\n", usl->value, mode);
@@ -726,7 +725,7 @@ void uwsgi_as_root() {
uwsgi_foreach(usl, uwsgi.call_as_root) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
}
}
@@ -944,7 +943,7 @@ void uwsgi_as_root() {
uwsgi_foreach(usl, uwsgi.call_as_user) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
exit(1);
}
}
@@ -1222,7 +1221,7 @@ void uwsgi_linux_ksm_map(void) {
}
// we now have areas
if (uwsgi.ksm_mappings_last_size == 0 || uwsgi.ksm_mappings_current_size != uwsgi.ksm_mappings_last_size) {
if (uwsgi.ksm_mappings_last_size == 0 || uwsgi.ksm_mappings_current_size == 0 || uwsgi.ksm_mappings_current_size != uwsgi.ksm_mappings_last_size) {
dirty = 1;
}
else {
@@ -1550,14 +1549,14 @@ void parse_sys_envs(char **envs) {
while (*uenvs) {
if (!strncmp(*uenvs, "UWSGI_", 6) &&
strncmp(*uenvs, "UWSGI_RELOADS=", 14) &&
strncmp(*uenvs, "UWSGI_VASSALS_DIR=", 18) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD=", 17) &&
strncmp(*uenvs, "UWSGI_BROODLORD_NUM=", 20) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD_CONFIG=", 24) &&
strncmp(*uenvs, "UWSGI_EMPEROR_PROXY=", 20) &&
strncmp(*uenvs, "UWSGI_JAIL_PID=", 15) &&
strncmp(*uenvs, "UWSGI_ORIGINAL_PROC_NAME=", 25)) {
strncmp(*uenvs, "UWSGI_RELOADS=", 14) &&
strncmp(*uenvs, "UWSGI_VASSALS_DIR=", 18) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD=", 17) &&
strncmp(*uenvs, "UWSGI_BROODLORD_NUM=", 20) &&
strncmp(*uenvs, "UWSGI_EMPEROR_FD_CONFIG=", 24) &&
strncmp(*uenvs, "UWSGI_EMPEROR_PROXY=", 20) &&
strncmp(*uenvs, "UWSGI_JAIL_PID=", 15) &&
strncmp(*uenvs, "UWSGI_ORIGINAL_PROC_NAME=", 25)) {
earg = uwsgi_malloc(strlen(*uenvs + 6) + 1);
env_to_arg(*uenvs + 6, earg);
eq_pos = strchr(earg, '=');
@@ -3167,169 +3166,45 @@ void escape_json(char *src, size_t len, char *dst) {
*ptr++ = 0;
}
/*
build PATH_INFO from raw_uri
it manages:
percent encoding
dot_segments removal
stop at the first #
*/
void http_url_decode(char *buf, uint16_t * len, char *dst) {
enum {
zero = 0,
percent1,
percent2,
slash,
dot,
dotdot
} status;
uint16_t i, current_new_len, new_len = 0;
uint16_t i;
int percent = 0;
char value[2];
size_t new_len = 0;
char *ptr = dst;
value[0] = '0';
value[1] = '0';
status = zero;
int no_slash = 0;
if (*len > 0 && buf[0] != '/') {
status = slash;
no_slash = 1;
}
for (i = 0; i < *len; i++) {
char c = buf[i];
if (c == '#') break;
switch(status) {
case zero:
if (c == '%') {
status = percent1;
break;
}
if (c == '/') {
status = slash;
break;
}
*ptr++ = c;
new_len++;
break;
case percent1:
if (c == '%') {
*ptr++ = '%';
new_len++;
status = zero;
break;
}
value[0] = c;
status = percent2;
break;
case percent2:
value[1] = c;
*ptr++ = hex2num(value);
new_len++;
status = zero;
break;
case slash:
if (c == '.') {
status = dot;
break;
}
// we could be at the first round (in non slash)
if (i > 0 || !no_slash) {
*ptr++ = '/'; new_len++;
}
if (c == '%') {
status = percent1;
break;
}
if (c == '/') {
status = slash;
break;
}
*ptr++ = c; new_len++;
status = zero;
break;
case dot:
if (c == '.') {
status = dotdot;
break;
}
if (c == '/') {
status = slash;
break;
}
if (i > 1) {
*ptr++ = '/'; new_len++;
}
*ptr++ = '.'; new_len++;
if (c == '%') {
status = percent1;
break;
}
*ptr++ = c; new_len++;
status = zero;
break;
case dotdot:
// here we need to remove a segment
if (c == '/') {
current_new_len = new_len;
while(current_new_len) {
current_new_len--;
ptr--;
if (dst[current_new_len] == '/') {
break;
}
}
new_len = current_new_len;
status = slash;
break;
}
if (i > 2) {
*ptr++ = '/'; new_len++;
}
*ptr++ = '.'; new_len++;
*ptr++ = '.'; new_len++;
if (c == '%') {
status = percent1;
break;
}
*ptr++ = c; new_len++;
status = zero;
break;
// over engineering
default:
*ptr++ = c;
new_len++;
break;
}
}
switch(status) {
case slash:
case dot:
*ptr++ = '/'; new_len++;
break;
case dotdot:
current_new_len = new_len;
while(current_new_len) {
if (dst[current_new_len-1] == '/') {
break;
}
current_new_len--;
if (buf[i] == '%') {
if (percent == 0) {
percent = 1;
}
new_len = current_new_len;
break;
default:
break;
else {
*ptr++ = '%';
new_len++;
percent = 0;
}
}
else {
if (percent == 1) {
value[0] = buf[i];
percent = 2;
}
else if (percent == 2) {
value[1] = buf[i];
*ptr++ = hex2num(value);
percent = 0;
new_len++;
}
else {
*ptr++ = buf[i];
new_len++;
}
}
}
*len = new_len;
@@ -3543,11 +3418,7 @@ int uwsgi_write_intfile(char *filename, int n) {
uwsgi_error_open(filename);
exit(1);
}
if (fprintf(pidfile, "%d\n", n) <= 0 || ferror(pidfile)) {
fclose(pidfile);
return -1;
}
if (fclose(pidfile)) {
if (fprintf(pidfile, "%d\n", n) <= 0 || ferror(pidfile) || fclose(pidfile)) {
return -1;
}
return 0;
@@ -3972,22 +3843,27 @@ void uwsgi_uuid(char *buf) {
uuid_unparse(uuid_zmq, buf);
#else
int i,r[11];
if (!uwsgi_file_exists("/dev/urandom")) goto fallback;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) goto fallback;
for(i=0;i<11;i++) {
if (read(fd, &r[i], 4) != 4) {
close(fd); goto fallback;
}
}
close(fd);
goto done;
static int srand_called = 0;
if (!uwsgi_file_exists("/dev/urandom")) goto fallback;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) goto fallback;
for(i=0;i<11;i++) {
if (read(fd, &r[i], 4) != 4) {
close(fd); goto fallback;
}
}
close(fd);
goto done;
fallback:
for(i=0;i<11;i++) {
r[i] = rand();
}
if (!srand_called) {
srand((unsigned int) getpid());
srand_called = 1;
}
for(i=0;i<11;i++) {
r[i] = rand();
}
done:
snprintf(buf, 37, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10]);
snprintf(buf, 37, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10]);
#endif
}
@@ -4351,7 +4227,6 @@ void uwsgi_envdir(char *edir) {
free(content);
}
closedir(d);
}
void uwsgi_envdirs(struct uwsgi_string_list *envdirs) {
@@ -4371,17 +4246,3 @@ void uwsgi_exit(int status) {
// disable macro expansion
(exit) (status);
}
int uwsgi_base128(struct uwsgi_buffer *ub, uint64_t l, int first) {
if( l > 127 ) {
if (uwsgi_base128(ub, l/128, 0)) return -1;
}
l %= 128;
if(first) {
if (uwsgi_buffer_u8(ub, (uint8_t) l)) return -1;
}
else {
if (uwsgi_buffer_u8(ub, 0x80 | (uint8_t) l)) return -1;
}
return 0;
}
+6 -33
View File
@@ -57,8 +57,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"raw-modifier1", required_argument, 0, "force the specified modifier1 when using RAW protocol", uwsgi_opt_set_64bit, &uwsgi.raw_modifier1, 0},
{"raw-modifier2", required_argument, 0, "force the specified modifier2 when using RAW protocol", uwsgi_opt_set_64bit, &uwsgi.raw_modifier2, 0},
{"puwsgi-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using persistent uwsgi protocol (puwsgi)", uwsgi_opt_add_socket, "puwsgi", 0},
{"protocol", required_argument, 0, "force the specified protocol for default sockets", uwsgi_opt_set_str, &uwsgi.protocol, 0},
{"socket-protocol", required_argument, 0, "force the specified protocol for default sockets", uwsgi_opt_set_str, &uwsgi.protocol, 0},
{"shared-socket", required_argument, 0, "create a shared sacket for advanced jailing or ipc", uwsgi_opt_add_shared_socket, NULL, 0},
@@ -222,11 +220,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"vassals-start-hook", required_argument, 0, "run the specified command before each vassal starts", uwsgi_opt_set_str, &uwsgi.vassals_start_hook, 0},
{"vassals-stop-hook", required_argument, 0, "run the specified command after vassal's death", uwsgi_opt_set_str, &uwsgi.vassals_stop_hook, 0},
{"vassal-sos-backlog", required_argument, 0, "ask emperor for sos if backlog queue has more items than the value specified", uwsgi_opt_set_int, &uwsgi.vassal_sos_backlog, 0},
{"vassals-set", required_argument, 0, "automatically set the specified option (via --set) for every vassal", uwsgi_opt_add_string_list, &uwsgi.vassals_set, 0},
{"vassal-set", required_argument, 0, "automatically set the specified option (via --set) for every vassal", uwsgi_opt_add_string_list, &uwsgi.vassals_set, 0},
{"heartbeat", required_argument, 0, "announce healtness to the emperor", uwsgi_opt_set_int, &uwsgi.heartbeat, 0},
{"auto-snapshot", optional_argument, 0, "automatically make workers snaphost after reload", uwsgi_opt_set_int, &uwsgi.auto_snapshot, UWSGI_OPT_LAZY},
{"reload-mercy", required_argument, 0, "set the maximum time (in seconds) we wait for workers and other processes to die during reload/shutdown", uwsgi_opt_set_int, &uwsgi.reload_mercy, 0},
{"worker-reload-mercy", required_argument, 0, "set the maximum time (in seconds) a worker can take to reload/shutdown (default is 60)", uwsgi_opt_set_int, &uwsgi.worker_reload_mercy, 0},
@@ -510,22 +504,13 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"reload-on-exception-repr", required_argument, 0, "reload a worker when a specific exception type+value (language-specific) is raised", uwsgi_opt_add_string_list, &uwsgi.reload_on_exception_repr, 0},
{"exception-handler", required_argument, 0, "add an exception handler", uwsgi_opt_add_string_list, &uwsgi.exception_handlers_instance, UWSGI_OPT_MASTER},
{"enable-metrics", no_argument, 0, "enable metrics subsystem", uwsgi_opt_true, &uwsgi.has_metrics, UWSGI_OPT_MASTER},
{"metric", required_argument, 0, "add a custom metric", uwsgi_opt_add_string_list, &uwsgi.additional_metrics, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-threshold", required_argument, 0, "add a metric threshold/alarm", uwsgi_opt_add_string_list, &uwsgi.metrics_threshold, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-alarm", required_argument, 0, "add a metric threshold/alarm", uwsgi_opt_add_string_list, &uwsgi.metrics_threshold, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metrics-dir", required_argument, 0, "exports metrics as text files in the specified directory", uwsgi_opt_set_str, &uwsgi.metrics_dir, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metrics-dir-restore", no_argument, 0, "restore last value taken from the metrics dir", uwsgi_opt_true, &uwsgi.metrics_dir_restore, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-dir", required_argument, 0, "exports metrics as text files in the specified directory", uwsgi_opt_set_str, &uwsgi.metrics_dir, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"metric-dir-restore", no_argument, 0, "restore last value taken from the metrics dir", uwsgi_opt_true, &uwsgi.metrics_dir_restore, UWSGI_OPT_METRICS|UWSGI_OPT_MASTER},
{"udp", required_argument, 0, "run the udp server on the specified address", uwsgi_opt_set_str, &uwsgi.udp_socket, UWSGI_OPT_MASTER},
{"stats", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER},
{"stats-server", required_argument, 0, "enable the stats server on the specified address", uwsgi_opt_set_str, &uwsgi.stats, UWSGI_OPT_MASTER},
{"stats-http", no_argument, 0, "prefix stats server json output with http headers", uwsgi_opt_true, &uwsgi.stats_http, UWSGI_OPT_MASTER},
{"stats-minified", no_argument, 0, "minify statistics json output", uwsgi_opt_true, &uwsgi.stats_minified, UWSGI_OPT_MASTER},
{"stats-min", no_argument, 0, "minify statistics json output", uwsgi_opt_true, &uwsgi.stats_minified, UWSGI_OPT_MASTER},
{"stats-push", required_argument, 0, "push the stats json to the specified destination", uwsgi_opt_add_string_list, &uwsgi.requested_stats_pushers, UWSGI_OPT_MASTER|UWSGI_OPT_METRICS},
{"stats-push", required_argument, 0, "push the stats json to the specified destination", uwsgi_opt_add_string_list, &uwsgi.requested_stats_pushers, UWSGI_OPT_MASTER},
{"stats-pusher-default-freq", required_argument, 0, "set the default frequency of stats pushers", uwsgi_opt_set_int, &uwsgi.stats_pusher_default_freq, UWSGI_OPT_MASTER},
{"stats-pushers-default-freq", required_argument, 0, "set the default frequency of stats pushers", uwsgi_opt_set_int, &uwsgi.stats_pusher_default_freq, UWSGI_OPT_MASTER},
{"multicast", required_argument, 0, "subscribe to specified multicast group", uwsgi_opt_set_str, &uwsgi.multicast_group, UWSGI_OPT_MASTER},
@@ -643,7 +628,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"log-master-req-stream", no_argument, 0, "create the master requests logpipe as SOCK_STREAM", uwsgi_opt_true, &uwsgi.log_master_req_stream, 0},
{"log-reopen", no_argument, 0, "reopen log after reload", uwsgi_opt_true, &uwsgi.log_reopen, 0},
{"log-truncate", no_argument, 0, "truncate log on startup", uwsgi_opt_true, &uwsgi.log_truncate, 0},
{"log-maxsize", required_argument, 0, "set maximum logfile size", uwsgi_opt_set_64bit, &uwsgi.log_maxsize, UWSGI_OPT_LOG_MASTER},
{"log-maxsize", required_argument, 0, "set maximum logfile size", uwsgi_opt_set_int, &uwsgi.log_maxsize, UWSGI_OPT_LOG_MASTER},
{"log-backupname", required_argument, 0, "set logfile name after rotation", uwsgi_opt_set_str, &uwsgi.log_backupname, 0},
{"logdate", optional_argument, 0, "prefix logs with date or a strftime string", uwsgi_opt_log_date, NULL, 0},
@@ -1456,7 +1441,7 @@ void uwsgi_exec_atexit(void) {
uwsgi_foreach(usl, uwsgi.call_as_user_atexit) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
}
}
}
@@ -1869,10 +1854,6 @@ static struct uwsgi_clock uwsgi_unix_clock = {
.microseconds = uwsgi_unix_microseconds,
};
void uwsgi_init_random() {
srand((unsigned int) (uwsgi.start_tv.tv_usec * uwsgi.start_tv.tv_sec));
}
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int argc, char *argv[], char *envp[]) {
@@ -1966,9 +1947,6 @@ int main(int argc, char *argv[], char *envp[]) {
// get startup time
gettimeofday(&uwsgi.start_tv, NULL);
// initialize random engine
uwsgi_init_random();
setlinebuf(stdout);
uwsgi.rl.rlim_cur = 0;
@@ -2026,9 +2004,6 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_register_base_hooks();
uwsgi_log_encoders_register_embedded();
// register base metrics (so plugins can override them)
uwsgi_metrics_collectors_setup();
//initialize embedded plugins
UWSGI_LOAD_EMBEDDED_PLUGINS
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
@@ -2163,6 +2138,7 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi_register_imperial_monitor("glob", uwsgi_imperial_monitor_glob_init, uwsgi_imperial_monitor_glob);
// setup stats pushers
uwsgi_register_stats_pusher("file", uwsgi_stats_pusher_file);
uwsgi_stats_pusher_setup();
// register embedded alarms
@@ -2867,9 +2843,6 @@ unsafe:
// set a default request structure (for loading apps...)
uwsgi.wsgi_req = &uwsgi.workers[0].cores[0].req;
// ok, let's inizialize the metrics subsystem
uwsgi_setup_metrics();
// cores are allocated, lets allocate logformat (if required)
if (uwsgi.logformat) {
uwsgi_build_log_format(uwsgi.logformat);
@@ -3535,7 +3508,7 @@ void uwsgi_init_all_apps() {
uwsgi_foreach(usl, uwsgi.call_pre_app) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
exit(1);
}
}
@@ -3603,7 +3576,7 @@ void uwsgi_init_all_apps() {
uwsgi_foreach(usl, uwsgi.call_post_app) {
if (uwsgi_call_symbol(usl->value)) {
uwsgi_log("unable to call function \"%s\"\n", usl->value);
uwsgi_log("unaable to call function \"%s\"\n", usl->value);
}
}
+1 -1
View File
@@ -59,7 +59,7 @@ static int uwsgi_websockets_check_pingpong(struct wsgi_request *wsgi_req) {
}
return 0;
}
// pong received, send another ping
// pong received, send anther ping
if (now - wsgi_req->websocket_last_ping >= uwsgi.websockets_ping_freq) {
return uwsgi_websockets_ping(wsgi_req);
}
+33 -27
View File
@@ -26,6 +26,9 @@ struct uwsgi_carbon {
unsigned long long *last_busyness_values;
unsigned long long *current_busyness_values;
int *was_busy;
int need_retry;
time_t last_update;
time_t next_retry;
int max_retries;
int retry_delay;
char *root_node;
@@ -37,7 +40,6 @@ struct uwsgi_carbon {
int zero_avg;
uint64_t last_requests;
struct uwsgi_stats_pusher *pusher;
int use_metrics;
} u_carbon;
static struct uwsgi_option carbon_options[] = {
@@ -53,7 +55,6 @@ static struct uwsgi_option carbon_options[] = {
{"carbon-name-resolve", no_argument, 0, "allow using hostname as carbon server address (default disabled)", uwsgi_opt_true, &u_carbon.resolve_hostname, 0},
{"carbon-resolve-names", no_argument, 0, "allow using hostname as carbon server address (default disabled)", uwsgi_opt_true, &u_carbon.resolve_hostname, 0},
{"carbon-idle-avg", required_argument, 0, "average values source during idle period (no requests), can be \"last\", \"zero\", \"none\" (default is last)", uwsgi_opt_set_str, &u_carbon.idle_avg, 0},
{"carbon-use-metrics", no_argument, 0, "don't compute all statistics, use metrics subsystem data instead (warning! key names will be different", uwsgi_opt_true, &u_carbon.use_metrics, 0},
{0, 0, 0, 0, 0, 0, 0},
};
@@ -107,7 +108,7 @@ static void carbon_post_init() {
if (u_carbon.freq < 1) u_carbon.freq = 60;
if (u_carbon.timeout < 1) u_carbon.timeout = 3;
if (u_carbon.max_retries < 0) u_carbon.max_retries = 0;
if (u_carbon.max_retries <= 0) u_carbon.max_retries = 1;
if (u_carbon.retry_delay <= 0) u_carbon.retry_delay = 7;
if (!u_carbon.id) {
u_carbon.id = uwsgi_str(uwsgi.sockets->name);
@@ -152,13 +153,14 @@ static void carbon_post_init() {
u_carbon.was_busy = uwsgi_calloc(sizeof(int) * uwsgi.numproc);
}
// set next update to now()+retry_delay, this way we will have first flush just after start
u_carbon.last_update = uwsgi_now() - u_carbon.freq + u_carbon.retry_delay;
uwsgi_log("[carbon] carbon plugin started, %is frequency, %is timeout, max retries %i, retry delay %is\n",
u_carbon.freq, u_carbon.timeout, u_carbon.max_retries, u_carbon.retry_delay);
struct uwsgi_stats_pusher_instance *uspi = uwsgi_stats_pusher_add(u_carbon.pusher, NULL);
uspi->freq = u_carbon.freq;
uspi->retry_delay = u_carbon.retry_delay;
uspi->max_retries = u_carbon.max_retries;
// no need to generate the json
uspi->raw=1;
}
@@ -183,15 +185,14 @@ static int carbon_write(int fd, char *fmt,...) {
return 1;
}
static int carbon_push_stats(int retry_cycle, time_t now) {
static void carbon_push_stats(int retry_cycle, time_t now) {
struct carbon_server_list *usl = u_carbon.servers_data;
if (!u_carbon.servers_data) return 0;
if (!u_carbon.servers_data) return;
int i;
int fd;
int wok;
char *ip;
char *carbon_address = NULL;
int needs_retry;
for (i = 0; i < uwsgi.numproc; i++) {
u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i];
@@ -199,7 +200,7 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
u_carbon.was_busy[i-1] += uwsgi_worker_is_busy(i+1);
}
needs_retry = 0;
u_carbon.need_retry = 0;
while(usl) {
if (retry_cycle && usl->healthy)
// skip healthy servers during retry cycle
@@ -227,7 +228,15 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
fd = uwsgi_connect(carbon_address, u_carbon.timeout, 0);
if (fd < 0) {
uwsgi_log("[carbon] Could not connect to carbon server at %s\n", carbon_address);
needs_retry = 1;
if (usl->errors < u_carbon.max_retries) {
u_carbon.need_retry = 1;
u_carbon.next_retry = uwsgi_now() + u_carbon.retry_delay;
} else {
uwsgi_log("[carbon] Maximum number of retries for %s (%d)\n",
carbon_address, u_carbon.max_retries);
usl->healthy = 0;
usl->errors = 0;
}
usl->healthy = 0;
usl->errors++;
free(carbon_address);
@@ -237,8 +246,6 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
// put the socket in non-blocking mode
uwsgi_socket_nb(fd);
if (u_carbon.use_metrics) goto metrics_loop;
unsigned long long total_rss = 0;
unsigned long long total_vsz = 0;
unsigned long long total_tx = 0;
@@ -373,18 +380,6 @@ static int carbon_push_stats(int retry_cycle, time_t now) {
wok = carbon_write(fd, "%s%s.%s.harakiri %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) now);
if (!wok) goto clear;
metrics_loop:
if (u_carbon.use_metrics) {
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
uwsgi_rlock(uwsgi.metrics_lock);
wok = carbon_write(fd, "%s%s.%s.%.*s %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, um->name_len, um->name, (unsigned long long) *um->value, (unsigned long long) now);
uwsgi_rwunlock(uwsgi.metrics_lock);
if (!wok) goto clear;
um = um->next;
}
}
usl->healthy = 1;
usl->errors = 0;
@@ -395,12 +390,23 @@ clear:
nxt:
usl = usl->next;
}
return needs_retry;
if (!retry_cycle) u_carbon.last_update = uwsgi_now();
if (u_carbon.need_retry)
// timeouts and retries might cause additional lags in carbon cycles, we will adjust timer to fix that
u_carbon.last_update -= u_carbon.timeout;
}
static void carbon_push(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
uspi->needs_retry = carbon_push_stats(uspi->retries, now);
if (u_carbon.need_retry && now >= u_carbon.next_retry) {
carbon_push_stats(1, now);
}
else {
// update
u_carbon.need_retry = 0;
carbon_push_stats(0, now);
}
}
static void carbon_cleanup() {
+1 -1
View File
@@ -166,7 +166,7 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
}
}
// destroy an instance
else if (!uwsgi_strncmp(ez_cmd, ez_cmd_len, "destroy", 7)) {
else if (!uwsgi_strncmp(ez_cmd, ez_cmd_len, "destroy", 6)) {
struct uwsgi_instance *ui = emperor_get(name);
if (!ui) {
uwsgi_log("[emperor-zeromq] unknown instance \"%s\"\n", name);
+1 -3
View File
@@ -291,9 +291,7 @@ request:
}
end:
if (greenlet_switch) {
Py_DECREF(greenlet_switch);
}
Py_DECREF(greenlet_switch);
end2:
Py_DECREF(current_greenlet);
+3 -39
View File
@@ -16,22 +16,6 @@ static struct uwsgi_option greenlet_options[] = {
{ 0, 0, 0, 0, 0, 0, 0 }
};
struct wsgi_request *uwsgi_greenlet_current_wsgi_req(void) {
struct wsgi_request *wsgi_req = NULL;
PyObject *current_greenlet = (PyObject *)PyGreenlet_GetCurrent();
PyObject *py_wsgi_req = PyObject_GetAttrString(current_greenlet, "uwsgi_wsgi_req");
// not in greenlet
if (!py_wsgi_req) {
uwsgi_log("[BUG] current_wsgi_req NOT FOUND !!!\n");
goto end;
}
wsgi_req = (struct wsgi_request*) PyLong_AsLong(py_wsgi_req);
Py_DECREF(py_wsgi_req);
end:
Py_DECREF(current_greenlet);
return wsgi_req;
}
static void gil_greenlet_get() {
pthread_setspecific(up.upt_gil_key, (void *) PyGILState_Ensure());
}
@@ -42,11 +26,9 @@ static void gil_greenlet_release() {
static PyObject *py_uwsgi_greenlet_request(PyObject * self, PyObject *args) {
struct wsgi_request *wsgi_req = uwsgi.wsgi_req;
async_schedule_to_req_green();
Py_DECREF(ugl.gl[wsgi_req->async_id]);
Py_DECREF(ugl.gl[uwsgi.wsgi_req->async_id]);
Py_INCREF(Py_None);
return Py_None;
@@ -64,7 +46,6 @@ static void greenlet_schedule_to_req() {
if (!uwsgi.wsgi_req->suspended) {
ugl.gl[id] = PyGreenlet_New(ugl.callable, NULL);
PyObject_SetAttrString((PyObject *)ugl.gl[id], "uwsgi_wsgi_req", PyLong_FromLong((long) uwsgi.wsgi_req));
uwsgi.wsgi_req->suspended = 1;
}
@@ -73,13 +54,7 @@ static void greenlet_schedule_to_req() {
uwsgi.p[modifier1]->suspend(NULL);
}
PyObject *ret = PyGreenlet_Switch(ugl.gl[id], NULL, NULL);
if (!ret) {
PyErr_Print();
uwsgi_log_verbose("[BUG] unable to switch greenlet !!!\n");
exit(1);
}
Py_DECREF(ret);
PyGreenlet_Switch(ugl.gl[id], NULL, NULL);
if (uwsgi.p[modifier1]->resume) {
uwsgi.p[modifier1]->resume(NULL);
@@ -96,13 +71,7 @@ static void greenlet_schedule_to_main(struct wsgi_request *wsgi_req) {
if (uwsgi.p[wsgi_req->uh->modifier1]->suspend) {
uwsgi.p[wsgi_req->uh->modifier1]->suspend(wsgi_req);
}
PyObject *ret = PyGreenlet_Switch(ugl.main, NULL, NULL);
if (!ret) {
PyErr_Print();
uwsgi_log_verbose("[BUG] unable to switch greenlet !!!\n");
exit(1);
}
Py_DECREF(ret);
PyGreenlet_Switch(ugl.main, NULL, NULL);
if (uwsgi.p[wsgi_req->uh->modifier1]->resume) {
uwsgi.p[wsgi_req->uh->modifier1]->resume(wsgi_req);
}
@@ -124,9 +93,6 @@ static void greenlet_init_apps(void) {
up.gil_release = gil_greenlet_release;
}
// map wsgi_req to greenlet object
uwsgi.current_wsgi_req = uwsgi_greenlet_current_wsgi_req;
// blindy call it as the stackless gil engine is already set
UWSGI_GET_GIL
@@ -135,9 +101,7 @@ static void greenlet_init_apps(void) {
ugl.gl = uwsgi_malloc( sizeof(PyGreenlet *) * uwsgi.async );
ugl.main = PyGreenlet_GetCurrent();
Py_INCREF(ugl.main);
ugl.callable = PyCFunction_New(uwsgi_greenlet_request_method, NULL);
Py_INCREF(ugl.callable);
uwsgi_log("enabled greenlet engine\n");
uwsgi.schedule_to_main = greenlet_schedule_to_main;
+1 -5
View File
@@ -7,11 +7,7 @@ JVM_INCPATH = None
JVM_LIBPATH = None
operating_system = os.uname()[0].lower()
try:
arch = os.environ['JVM_ARCH']
except:
arch = os.uname()[4].lower()
arch = os.uname()[4].lower()
if arch in ('i686', 'x86', 'x86_32'):
arch = 'i386'
+1 -5
View File
@@ -76,16 +76,12 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
if (!headers) { uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;}
// generate headers
int headers_len = (int) av_len(headers);
for(i=0; i<=headers_len; i++) {
for(i=0; i<=av_len(headers); i++) {
hitem = av_fetch(headers,i,0);
if (!*hitem) {
uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;
}
chitem = SvPV(*hitem, hlen);
if (i+1 > headers_len) {
uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;
}
hitem = av_fetch(headers,i+1,0);
if (!*hitem) {
uwsgi_log("invalid PSGI headers\n"); return UWSGI_OK;
-104
View File
@@ -524,103 +524,6 @@ XS(XS_add_rb_timer) {
XSRETURN(1);
}
XS(XS_metric_inc) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_inc(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_dec) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_dec(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_mul) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_mul(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_div) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 1;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
if (items > 1) {
value = (int64_t) SvIV(ST(1));
}
if (uwsgi_metric_div(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_set) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
int64_t value = 0;
psgi_check_args(2);
metric = SvPV(ST(0), metric_len);
value = (int64_t) SvIV(ST(1));
if (uwsgi_metric_set(metric, NULL, value)) {
croak("unable to update metric");
XSRETURN_UNDEF;
}
XSRETURN_YES;
}
XS(XS_metric_get) {
dXSARGS;
char *metric = NULL;
STRLEN metric_len = 0;
psgi_check_args(1);
metric = SvPV(ST(0), metric_len);
ST(0) = newSViv(uwsgi_metric_get(metric, NULL));
sv_2mortal(ST(0));
XSRETURN(1);
}
void init_perl_embedded_module() {
@@ -658,12 +561,5 @@ void init_perl_embedded_module() {
psgi_xs(add_rb_timer);
psgi_xs(set_user_harakiri);
psgi_xs(metric_inc);
psgi_xs(metric_dec);
psgi_xs(metric_mul);
psgi_xs(metric_div);
psgi_xs(metric_get);
psgi_xs(metric_set);
}
-1
View File
@@ -149,7 +149,6 @@ static void *uwsgi_pty_loop(void *arg) {
if (rlen == 0) exit(1);
if (rlen < 0) {
uwsgi_error("uwsgi_pty_loop()/read()");
continue;
}
if (upty.log && upty.original_log >= 0) {
if (write(upty.original_log, buf, rlen) != rlen) {
-1
View File
@@ -313,7 +313,6 @@ static void uwsgi_pypy_onload() {
#ifdef UWSGI_PYPY_HOME
upypy.home = UWSGI_PYPY_HOME;
#endif
uwsgi.has_threads = 1;
}
static int uwsgi_pypy_mule(char *opt) {
-13
View File
@@ -235,13 +235,6 @@ int uwsgi_ready_fd(struct wsgi_request *);
void set_user_harakiri(int);
int uwsgi_metric_set(char *, char *, int64_t);
int uwsgi_metric_inc(char *, char *, int64_t);
int uwsgi_metric_dec(char *, char *, int64_t);
int uwsgi_metric_mul(char *, char *, int64_t);
int uwsgi_metric_div(char *, char *, int64_t);
int64_t uwsgi_metric_get(char *, char *);
%s
''' % ('\n'.join(uwsgi_cdef), hooks)
@@ -541,12 +534,6 @@ uwsgi.call = uwsgi_pypy_call
uwsgi.signal = lambda x: lib.uwsgi_signal_send(lib.uwsgi.signal_socket, x)
uwsgi.metric_get = lambda x: lib.uwsgi_metric_get(x, ffi.NULL)
uwsgi.metric_set = lambda x, y: lib.uwsgi_metric_set(x, ffi.NULL, y)
uwsgi.metric_inc = lambda x, y=1: lib.uwsgi_metric_inc(x, ffi.NULL, y)
uwsgi.metric_dec = lambda x, y=1: lib.uwsgi_metric_dec(x, ffi.NULL, y)
uwsgi.metric_mul = lambda x, y=1: lib.uwsgi_metric_mul(x, ffi.NULL, y)
uwsgi.metric_div = lambda x, y=1: lib.uwsgi_metric_div(x, ffi.NULL, y)
def uwsgi_pypy_uwsgi_cache_get(key, cache=ffi.NULL):
vallen = ffi.new('uint64_t*')
-5
View File
@@ -227,10 +227,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
PyObject *callables_dict = get_uwsgi_pydict((char *)arg1);
if (callables_dict) {
wi->callable = PyDict_GetItem(callables_dict, (PyObject *)wi->callable);
if (!wi->callable) {
uwsgi_log("skipping broken app %s\n", wsgi_req->appid);
goto multiapp;
}
}
}
}
@@ -361,7 +357,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
uwsgi_apps_cnt++;
multiapp:
if (multiapp > 1) {
for(i=1;i<multiapp;i++) {
PyObject *app_mnt = PyList_GetItem(app_list, i);
-111
View File
@@ -3169,111 +3169,6 @@ static PyMethodDef uwsgi_queue_methods[] = {
{NULL, NULL},
};
PyObject *py_uwsgi_metric_inc(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_inc", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_inc(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_dec(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_dec", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_dec(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_mul(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_mul", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_mul(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_div(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_div", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_div(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_set(PyObject * self, PyObject * args) {
char *key;
int64_t value = 1;
if (!PyArg_ParseTuple(args, "s|l:metric_set", &key, &value)) return NULL;
UWSGI_RELEASE_GIL
if (uwsgi_metric_set(key, NULL, value)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_metric_get(PyObject * self, PyObject * args) {
char *key;
if (!PyArg_ParseTuple(args, "s:metric_get", &key)) return NULL;
UWSGI_RELEASE_GIL
int64_t value = uwsgi_metric_get(key, NULL);
UWSGI_GET_GIL
return PyLong_FromLongLong(value);
}
static PyMethodDef uwsgi_metrics_methods[] = {
{"metric_inc", py_uwsgi_metric_inc, METH_VARARGS, ""},
{"metric_dec", py_uwsgi_metric_dec, METH_VARARGS, ""},
{"metric_mul", py_uwsgi_metric_mul, METH_VARARGS, ""},
{"metric_div", py_uwsgi_metric_div, METH_VARARGS, ""},
{"metric_get", py_uwsgi_metric_get, METH_VARARGS, ""},
{"metric_set", py_uwsgi_metric_set, METH_VARARGS, ""},
{NULL, NULL},
};
void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) {
@@ -3309,12 +3204,6 @@ void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) {
Py_DECREF(func);
}
for (uwsgi_function = uwsgi_metrics_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
Py_DECREF(func);
}
}
void init_uwsgi_module_cache(PyObject * current_uwsgi_module) {
+2 -12
View File
@@ -18,15 +18,13 @@ extern PyTypeObject uwsgi_InputType;
*/
int uwsgi_python_send_body(struct wsgi_request *wsgi_req, PyObject *chunk) {
char *content = NULL;
size_t content_len = 0;
if (!up.wsgi_accept_buffer && !wsgi_req->is_raw) goto strict;
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
Py_buffer pbuf;
int has_buffer = 0;
#endif
char *content = NULL;
size_t content_len = 0;
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
if (PyObject_CheckBuffer(chunk)) {
if (!PyObject_GetBuffer(chunk, &pbuf, PyBUF_SIMPLE)) {
@@ -38,18 +36,10 @@ int uwsgi_python_send_body(struct wsgi_request *wsgi_req, PyObject *chunk) {
}
#else
if (PyObject_CheckReadBuffer(chunk)) {
#ifdef UWSGI_PYTHON_OLD
int buffer_len = 0;
if (!PyObject_AsCharBuffer(chunk, (const char **) &content, &buffer_len)) {
#else
if (!PyObject_AsCharBuffer(chunk, (const char **) &content, (Py_ssize_t *) &content_len)) {
#endif
PyErr_Clear();
goto found;
}
#ifdef UWSGI_PYTHON_OLD
content_len = buffer_len;
#endif
}
#endif
-89
View File
@@ -7,88 +7,6 @@ extern struct uwsgi_plugin rack_plugin;
#define uwsgi_rack_api(x, y, z) rb_define_module_function(rb_uwsgi_embedded, x, y, z)
static VALUE rack_uwsgi_metric_get(VALUE *class, VALUE key) {
Check_Type(key, T_STRING);
int64_t value = uwsgi_metric_get(RSTRING_PTR(key), NULL);
return LONG2NUM(value);
}
static VALUE rack_uwsgi_metric_set(VALUE *class, VALUE key, VALUE val) {
Check_Type(key, T_STRING);
Check_Type(val, T_FIXNUM); // should be T_BIGNUM...
if (uwsgi_metric_set(RSTRING_PTR(key), NULL, NUM2LONG(val) )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_inc(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_inc(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_dec(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_dec(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_mul(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_mul(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_metric_div(int argc, VALUE *argv, VALUE *class) {
int64_t value = 1;
if (argc == 0) return Qnil;
Check_Type(argv[0], T_STRING);
if (argc > 1) {
Check_Type(argv[1], T_FIXNUM); // should be T_BIGNUM...
value = NUM2LONG(argv[1]);
}
if (uwsgi_metric_div(RSTRING_PTR(argv[0]), NULL, value )) {
return Qnil;
}
return Qtrue;
}
static VALUE rack_uwsgi_warning(VALUE *class, VALUE rbmessage) {
Check_Type(rbmessage, T_STRING);
@@ -1181,13 +1099,6 @@ void uwsgi_rack_init_api() {
uwsgi_rack_api("cache_clear", rack_uwsgi_cache_clear, -1);
uwsgi_rack_api("cache_clear!", rack_uwsgi_cache_clear_exc, -1);
uwsgi_rack_api("metric_get", rack_uwsgi_metric_get, 1);
uwsgi_rack_api("metric_set", rack_uwsgi_metric_set, 2);
uwsgi_rack_api("metric_inc", rack_uwsgi_metric_inc, -1);
uwsgi_rack_api("metric_dec", rack_uwsgi_metric_dec, -1);
uwsgi_rack_api("metric_mul", rack_uwsgi_metric_mul, -1);
uwsgi_rack_api("metric_div", rack_uwsgi_metric_div, -1);
VALUE uwsgi_rb_opt_hash = rb_hash_new();
int i;
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
+1 -8
View File
@@ -57,8 +57,6 @@ struct uwsgi_router_cache_conf {
char *status_str;
int status;
char *no_offload;
char *no_cl;
};
// this is allocated for each transformation
@@ -191,9 +189,7 @@ static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_
if (expires) {
if (uwsgi_response_add_expires(wsgi_req, expires)) goto error;
}
if (!urcc->no_cl) {
if (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
}
if (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
if (wsgi_req->socket->can_offload && !ur->custom && !urcc->no_offload) {
if (!uwsgi_offload_request_memory_do(wsgi_req, value, valsize)) {
wsgi_req->via = UWSGI_VIA_OFFLOAD;
@@ -382,9 +378,6 @@ static int uwsgi_router_cache(struct uwsgi_route *ur, char *args) {
"mime", &urcc->mime,
"name", &urcc->name,
"no_offload", &urcc->no_offload,
"no_content_length", &urcc->no_cl,
"no_cl", &urcc->no_cl,
"nocl", &urcc->no_cl,
NULL)) {
uwsgi_log("invalid route syntax: %s\n", args);
exit(1);
+1 -1
View File
@@ -81,7 +81,7 @@ static int uwsgi_routing_func_hash(struct wsgi_request *wsgi_req, struct uwsgi_r
vallen = urhc->items_len;
}
// last item
else if (value != NULL) {
else {
vallen = (urhc->items + urhc->items_len) - value;
}
}
-135
View File
@@ -1,135 +0,0 @@
#include <uwsgi.h>
#ifdef UWSGI_ROUTING
struct uwsgi_router_metric_conf {
// the name of the metric
char *name;
size_t name_len;
// the value for the metric
char *value;
size_t value_len;
int (*func)(char *, char *, int64_t);
};
// metricinc/metricdec/metricmul/metricdiv/metricset
static int uwsgi_routing_func_metricmath(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
struct uwsgi_router_metric_conf *urmc = (struct uwsgi_router_metric_conf *) ur->data2;
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->name, urmc->name_len);
if (!ub) return UWSGI_ROUTE_BREAK;
struct uwsgi_buffer *ub_val = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->value, urmc->value_len);
if (!ub_val) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
int64_t num = strtol(ub_val->buf, NULL, 10);
uwsgi_buffer_destroy(ub_val);
if (urmc->func(ub->buf, NULL, num)) {
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_BREAK;
}
uwsgi_buffer_destroy(ub);
return UWSGI_ROUTE_NEXT;
}
static struct uwsgi_router_metric_conf *uwsgi_router_metricmath(struct uwsgi_route *ur, char *args) {
ur->func = uwsgi_routing_func_metricmath;
ur->data = args;
ur->data_len = strlen(args);
struct uwsgi_router_metric_conf *urmc = uwsgi_calloc(sizeof(struct uwsgi_router_metric_conf));
char *comma = strchr(args, ',');
if (comma) {
urmc->value = comma+1;
urmc->value_len = strlen(urmc->value);
*comma = 0;
}
else {
urmc->value = "1";
urmc->value_len = 1;
}
urmc->name = args;
urmc->name_len = strlen(args);
if (comma) *comma = ',';
ur->data2 = urmc;
return urmc;
}
static int uwsgi_router_metricinc(struct uwsgi_route *ur, char *args) {
struct uwsgi_router_metric_conf *urmc = uwsgi_router_metricmath(ur, args);
if (!urmc) return -1;
urmc->func = uwsgi_metric_inc;
return 0;
}
static int uwsgi_router_metricdec(struct uwsgi_route *ur, char *args) {
struct uwsgi_router_metric_conf *urmc = uwsgi_router_metricmath(ur, args);
if (!urmc) return -1;
urmc->func = uwsgi_metric_dec;
return 0;
}
static int uwsgi_router_metricmul(struct uwsgi_route *ur, char *args) {
struct uwsgi_router_metric_conf *urmc = uwsgi_router_metricmath(ur, args);
if (!urmc) return -1;
urmc->func = uwsgi_metric_mul;
return 0;
}
static int uwsgi_router_metricdiv(struct uwsgi_route *ur, char *args) {
struct uwsgi_router_metric_conf *urmc = uwsgi_router_metricmath(ur, args);
if (!urmc) return -1;
urmc->func = uwsgi_metric_div;
return 0;
}
static int uwsgi_router_metricset(struct uwsgi_route *ur, char *args) {
struct uwsgi_router_metric_conf *urmc = uwsgi_router_metricmath(ur, args);
if (!urmc) return -1;
urmc->func = uwsgi_metric_set;
return 0;
}
static char *uwsgi_route_var_metric(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
int64_t metric = uwsgi_metric_getn(key, keylen, NULL, 0);
char *ret = uwsgi_64bit2str(metric);
*vallen = strlen(ret);
return ret;
}
static void router_metrics_register() {
uwsgi_register_router("metricinc", uwsgi_router_metricinc);
uwsgi_register_router("metricdec", uwsgi_router_metricdec);
uwsgi_register_router("metricmul", uwsgi_router_metricmul);
uwsgi_register_router("metricdiv", uwsgi_router_metricdiv);
uwsgi_register_router("metricset", uwsgi_router_metricset);
struct uwsgi_route_var *urv = uwsgi_register_route_var("metric", uwsgi_route_var_metric);
urv->need_free = 1;
}
struct uwsgi_plugin router_metrics_plugin = {
.name = "router_metrics",
.on_load = router_metrics_register,
};
#else
struct uwsgi_plugin router_metrics_plugin = {
.name = "router_metrics",
};
#endif
-6
View File
@@ -1,6 +0,0 @@
NAME='router_metrics'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['plugin']
+1 -8
View File
@@ -16,8 +16,6 @@ struct uwsgi_router_file_conf {
size_t content_type_len;
char *mime;
char *no_cl;
};
int uwsgi_routing_func_static(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
@@ -66,9 +64,7 @@ int uwsgi_routing_func_file(struct wsgi_request *wsgi_req, struct uwsgi_route *u
goto end2;
}
uwsgi_buffer_destroy(ub_s);
if (!urfc->no_cl) {
if (uwsgi_response_add_content_length(wsgi_req, st.st_size)) goto end2;
}
if (uwsgi_response_add_content_length(wsgi_req, st.st_size)) goto end2;
if (urfc->mime) {
size_t mime_type_len = 0;
char *mime_type = uwsgi_get_mime_type(ub->buf, ub->pos, &mime_type_len);
@@ -252,9 +248,6 @@ static int uwsgi_router_file(struct uwsgi_route *ur, char *args) {
"filename", &urfc->filename,
"status", &urfc->status,
"content_type", &urfc->content_type,
"nocl", &urfc->no_cl,
"no_cl", &urfc->no_cl,
"no_content_length", &urfc->no_cl,
"mime", &urfc->mime,
NULL)) {
uwsgi_log("invalid file route syntax: %s\n", args);
+111 -122
View File
@@ -1,38 +1,30 @@
#include <uwsgi.h>
#include "../../uwsgi.h"
extern struct uwsgi_server uwsgi;
static struct uwsgi_rrdtool {
struct uwsgi_rrdtool {
void *lib;
char *lib_name;
int (*create)(int, char **);
int (*update)(int, char **);
struct uwsgi_string_list *rrd;
int max_ds;
int freq;
char *update_area;
struct uwsgi_string_list *directory;
struct uwsgi_stats_pusher *pusher;
} u_rrd;
static struct uwsgi_option rrdtool_options[] = {
{"rrdtool", required_argument, 0, "store rrd files in the specified directory", uwsgi_opt_add_string_list, &u_rrd.directory, UWSGI_OPT_MASTER|UWSGI_OPT_METRICS},
struct uwsgi_option rrdtool_options[] = {
{"rrdtool", required_argument, 0, "collect requests data in the specified rrd file", uwsgi_opt_add_string_list, &u_rrd.rrd, UWSGI_OPT_MASTER},
{"rrdtool-freq", required_argument, 0, "set collect frequency", uwsgi_opt_set_int, &u_rrd.freq, 0},
{"rrdtool-lib", required_argument, 0, "set the name of rrd library (default: librrd.so)", uwsgi_opt_set_str, &u_rrd.lib_name, 0},
{"rrdtool-max-ds", required_argument, 0, "set maximum number of data sources", uwsgi_opt_set_int, &u_rrd.max_ds, 0},
{0, 0, 0, 0, 0, 0, 0},
};
static int rrdtool_init() {
int rrdtool_init() {
if (!u_rrd.lib_name) {
u_rrd.lib_name = "librrd.so";
}
u_rrd.lib = dlopen(u_rrd.lib_name, RTLD_LAZY);
u_rrd.lib = dlopen("librrd.so", RTLD_LAZY);
if (!u_rrd.lib) return -1;
u_rrd.create = dlsym(u_rrd.lib, "rrd_create");
@@ -47,140 +39,137 @@ static int rrdtool_init() {
return -1;
}
if (!u_rrd.max_ds) u_rrd.max_ds = 30;
uwsgi_log_initial("*** RRDtool library available at %p ***\n", u_rrd.lib);
return 0;
}
/*
void rrdtool_post_init() {
create .rrd files if needed
struct uwsgi_string_list *usl = u_rrd.rrd;
char **argv;
int i;
*/
static void rrdtool_post_init() {
if (!u_rrd.create) return;
if (!u_rrd.lib || !u_rrd.create) return;
// do not waste time if no --rrdtool option is defiend
if (!u_rrd.directory) return;
if (!u_rrd.rrd) return;
if (!u_rrd.freq) u_rrd.freq = 300;
if (uwsgi.numproc > u_rrd.max_ds) {
uwsgi_log("!!! NOT ENOUGH SLOTS IN RRDTOOL DS TO HOST WORKERS DATA (increase them with --rrdtool-max-ds) !!!\n");
dlclose(u_rrd.lib);
return;
}
// alloc space for DS_REQ + DS WORKER + RRA + create + filename
argv = uwsgi_malloc( sizeof(char *) * (1 + u_rrd.max_ds + 4 + 1 +1));
char *argv[7];
argv[0] = "create";
argv[2] = "DS:requests:DERIVE:600:0:U";
// create RRA
argv[3] = "RRA:AVERAGE:0.5:1:288" ;
argv[4] = "RRA:AVERAGE:0.5:12:168" ;
argv[5] = "RRA:AVERAGE:0.5:288:31" ;
argv[6] = "RRA:AVERAGE:0.5:2016:52";
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, u_rrd.directory) {
char *dir = uwsgi_expand_path(usl->value, strlen(usl->value), NULL);
if (!dir) {
uwsgi_error("rrdtool_post_init()/uwsgi_expand_path()");
exit(1);
}
struct uwsgi_metric *um = uwsgi.metrics;
// here locking is useless, but maybe in the future we could move this part
// somewhere else
int created = 0;
uwsgi_rlock(uwsgi.metrics_lock);
while(um) {
char *filename = uwsgi_concat4(dir, "/", um->name, ".rrd");
if (!uwsgi_file_exists(filename)) {
argv[1] = filename;
if (um->type == UWSGI_METRIC_GAUGE) {
argv[2] = "DS:metric:GAUGE:600:0:U";
}
else {
argv[2] = "DS:metric:DERIVE:600:0:U";
}
if (u_rrd.create(7, argv)) {
uwsgi_log("unable to create rrd file for metric \"%s\"\n", um->name);
uwsgi_error("rrd_create()");
exit(1);
}
created++;
}
free(filename);
um = um->next;
}
uwsgi_rwunlock(uwsgi.metrics_lock);
uwsgi_log("created %d new rrd files in %s\n", created, dir);
struct uwsgi_stats_pusher_instance *uspi = uwsgi_stats_pusher_add(u_rrd.pusher, NULL);
uspi->freq = u_rrd.freq;
uspi->data = dir;
// no need to generate the json
uspi->raw=1;
}
}
static void rrdtool_push(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
if (!u_rrd.update) return ;
// standard stats pusher
if (!uspi->data) {
if (!uspi->arg) {
uwsgi_log("invalid rrdtool stats pusher syntax\n");
// create DS for workers
for(i=0;i<u_rrd.max_ds;i++) {
int max_size = sizeof("DS:worker65536:DERIVE:600:0:U")+1;
argv[3+i] = uwsgi_malloc( max_size );
if (snprintf(argv[3+i], max_size, "DS:worker%d:DERIVE:600:0:U", i+1) < 25) {
uwsgi_log("unable to create args for rrd_create()\n");
exit(1);
}
uspi->data = uwsgi_expand_path(uspi->arg, strlen(uspi->arg), NULL);
if (!uspi->data) {
uwsgi_error("rrdtool_push()/uwsgi_expand_path()");
exit(1);
}
// create RRA
argv[3+u_rrd.max_ds] = "RRA:AVERAGE:0.5:1:288" ;
argv[3+u_rrd.max_ds+1] = "RRA:AVERAGE:0.5:12:168" ;
argv[3+u_rrd.max_ds+2] = "RRA:AVERAGE:0.5:288:31" ;
argv[3+u_rrd.max_ds+3] = "RRA:AVERAGE:0.5:2016:52";
while(usl) {
if (!uwsgi_file_exists(usl->value)) {
argv[1] = usl->value;
if (u_rrd.create((1 + u_rrd.max_ds + 4 + 1 +1), argv)) {
uwsgi_error("rrd_create()");
exit(1);
}
}
if (!u_rrd.freq) u_rrd.freq = 300;
uspi->freq = u_rrd.freq;
char *new_usl_value = uwsgi_malloc(PATH_MAX+1);
if (!realpath(usl->value, new_usl_value)) {
uwsgi_error("realpath()");
exit(1);
}
usl->value = new_usl_value;
usl = usl->next;
}
// 1k will be more than enough
char buf[1024];
char *argv[3];
argv[0] = "update";
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
uwsgi_rlock(uwsgi.metrics_lock);
int ret = snprintf(buf, 1024, "N:%lld", (long long) (*um->value));
uwsgi_rwunlock(uwsgi.metrics_lock);
if (ret < 3) {
uwsgi_log("unable to update rrdtool metric for %s\n", um->name);
goto next;
}
char *filename = uwsgi_concat4(uspi->data, "/", um->name, ".rrd");
argv[1] = filename;
argv[2] = buf;
if (u_rrd.update(3, argv)) {
uwsgi_log_verbose("ERROR: rrd_update(\"%s\", \"%s\")\n", argv[1], argv[2]);
}
free(filename);
next:
um = um->next;
// free DS
for(i=0;i<u_rrd.max_ds;i++) {
free(argv[3+i]);
}
free(argv);
//now allocate memory for updates
u_rrd.update_area = uwsgi_malloc( 1+((1+sizeof(UMAX64_STR)) * (u_rrd.max_ds+1))+1 );
memset(u_rrd.update_area, 0, 1+((1+sizeof(UMAX64_STR)) * (u_rrd.max_ds+1))+1 );
u_rrd.update_area[0] = 'N';
if (u_rrd.freq < 1) u_rrd.freq = 300;
}
static void rrdtool_register() {
u_rrd.pusher = uwsgi_register_stats_pusher("rrdtool", rrdtool_push);
u_rrd.pusher->raw = 1;
void rrdtool_master_cycle() {
static time_t last_update = 0;
char *ptr;
int rlen, i;
char *argv[3];
struct uwsgi_string_list *usl = u_rrd.rrd;
if (!u_rrd.lib || !u_rrd.create || !u_rrd.rrd) return ;
if (last_update == 0) last_update = uwsgi_now();
// update
if (uwsgi.current_time - last_update >= u_rrd.freq) {
ptr = u_rrd.update_area+1;
rlen = snprintf(ptr, 1+sizeof(UMAX64_STR), ":%llu", (unsigned long long )uwsgi.workers[0].requests);
if (rlen < 2) return;
ptr+=rlen;
for(i=0;i<u_rrd.max_ds;i++) {
if (i+1 <= uwsgi.numproc) {
rlen = snprintf(ptr, 1+sizeof(UMAX64_STR), ":%llu", (unsigned long long )uwsgi.workers[1+i].requests);
if (rlen < 2) return;
}
else {
memcpy(ptr, ":U", 2);
rlen = 2;
}
ptr+=rlen;
}
last_update = uwsgi.current_time;
argv[0] = "update";
argv[2] = u_rrd.update_area;
while(usl) {
argv[1] = usl->value;
if (u_rrd.update(3, argv)) {
uwsgi_log_verbose("ERROR: rrd_update(\"%s\", \"%s\")\n", argv[1], argv[2]);
}
usl = usl->next;
}
}
}
struct uwsgi_plugin rrdtool_plugin = {
.name = "rrdtool",
.options = rrdtool_options,
.on_load = rrdtool_register,
.options = rrdtool_options,
// this is the best phase to create rrd files (if needed)
.preinit_apps = rrdtool_post_init,
// here we get pointers to rrdtool functions
.master_cycle = rrdtool_master_cycle,
.post_init = rrdtool_post_init,
.init = rrdtool_init,
};
-57
View File
@@ -1,57 +0,0 @@
#include <uwsgi.h>
struct uwsgi_stats_pusher_file_conf {
char *path;
char *freq;
char *separator;
};
static void stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
struct uwsgi_stats_pusher_file_conf *uspic = (struct uwsgi_stats_pusher_file_conf *) uspi->data;
if (!uspi->configured) {
uspic = uwsgi_calloc(sizeof(struct uwsgi_stats_pusher_file_conf));
if (uspi->arg) {
if (uwsgi_kvlist_parse(uspi->arg, strlen(uspi->arg), ',', '=', "path", &uspic->path, "separator", &uspic->separator, "freq", &uspic->freq, NULL)) {
free(uspi);
return;
}
}
if (!uspic->path)
uspic->path = "uwsgi.stats";
if (!uspic->separator)
uspic->separator = "\n\n";
if (uspic->freq)
uspi->freq = atoi(uspic->freq);
uspi->configured = 1;
uspi->data = uspic;
}
int fd = open(uspic->path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
if (fd < 0) {
uwsgi_error_open(uspic->path);
return;
}
ssize_t rlen = write(fd, json, json_len);
if (rlen != (ssize_t) json_len) {
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
}
rlen = write(fd, uspic->separator, strlen(uspic->separator));
if (rlen != (ssize_t) strlen(uspic->separator)) {
uwsgi_error("uwsgi_stats_pusher_file() -> write()\n");
}
close(fd);
}
static void stats_pusher_file_init(void) {
uwsgi_register_stats_pusher("file", stats_pusher_file);
}
struct uwsgi_plugin stats_pusher_file_plugin = {
.name = "stats_pusher_file",
.on_load = stats_pusher_file_init,
};
-7
View File
@@ -1,7 +0,0 @@
NAME='stats_pusher_file'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['plugin']
-111
View File
@@ -1,111 +0,0 @@
#include <uwsgi.h>
/*
this is a stats pusher plugin for sendign metrics over a udp socket
--stats-push socket:address[,prefix]
example:
--stats-push socket:127.0.0.1:8125,myinstance
it exports values exposed by the metric subsystem
(it is based on the statsd plugin)
*/
extern struct uwsgi_server uwsgi;
// configuration of a socket node
struct socket_node {
int fd;
union uwsgi_sockaddr addr;
socklen_t addr_len;
char *prefix;
uint16_t prefix_len;
};
static int socket_send_metric(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, struct uwsgi_metric *um) {
struct socket_node *sn = (struct socket_node *) uspi->data;
// reset the buffer
ub->pos = 0;
if (uwsgi_buffer_append(ub, sn->prefix, sn->prefix_len)) return -1;
if (uwsgi_buffer_append(ub, ".", 1)) return -1;
if (uwsgi_buffer_append(ub, um->name, um->name_len)) return -1;
if (uwsgi_buffer_append(ub, " ", 1)) return -1;
if (uwsgi_buffer_num64(ub, (int64_t) um->type)) return -1;
if (uwsgi_buffer_append(ub, " ", 1)) return -1;
if (uwsgi_buffer_num64(ub, *um->value)) return -1;
if (sendto(sn->fd, ub->buf, ub->pos, 0, (struct sockaddr *) &sn->addr.sa_in, sn->addr_len) < 0) {
uwsgi_error("socket_send_metric()/sendto()");
}
return 0;
}
static void stats_pusher_socket(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
if (!uspi->configured) {
struct socket_node *sn = uwsgi_calloc(sizeof(struct socket_node));
char *comma = strchr(uspi->arg, ',');
if (comma) {
sn->prefix = comma+1;
sn->prefix_len = strlen(sn->prefix);
*comma = 0;
}
else {
sn->prefix = "uwsgi";
sn->prefix_len = 5;
}
char *colon = strchr(uspi->arg, ':');
if (!colon) {
uwsgi_log("invalid socket address %s\n", uspi->arg);
if (comma) *comma = ',';
free(sn);
return;
}
sn->addr_len = socket_to_in_addr(uspi->arg, colon, 0, &sn->addr.sa_in);
sn->fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sn->fd < 0) {
uwsgi_error("stats_pusher_socket()/socket()");
if (comma) *comma = ',';
free(sn);
return;
}
uwsgi_socket_nb(sn->fd);
if (comma) *comma = ',';
uspi->data = sn;
uspi->configured = 1;
}
// we use the same buffer for all of the packets
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
uwsgi_rlock(uwsgi.metrics_lock);
socket_send_metric(ub, uspi, um);
uwsgi_rwunlock(uwsgi.metrics_lock);
um = um->next;
}
uwsgi_buffer_destroy(ub);
}
static void stats_pusher_socket_init(void) {
struct uwsgi_stats_pusher *usp = uwsgi_register_stats_pusher("socket", stats_pusher_socket);
// we use a custom format not the JSON one
usp->raw = 1;
}
struct uwsgi_plugin stats_pusher_socket_plugin = {
.name = "stats_pusher_socket",
.on_load = stats_pusher_socket_init,
};
@@ -1,7 +0,0 @@
NAME='stats_pusher_socket'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['plugin']
+46 -23
View File
@@ -10,7 +10,7 @@ example:
--stats-push statsd:127.0.0.1:8125,myinstance
it exports values exposed by the metric subsystem
it is pretty minimal, but will be extended after the 2.0 metric subsystem will be released
*/
@@ -25,23 +25,45 @@ struct statsd_node {
uint16_t prefix_len;
};
static int statsd_send_metric(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, char *metric, size_t metric_len, int64_t value, char type[2]) {
static int statsd_send_worker_gauge(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, int wid, char *metric, uint16_t metric_len, int64_t value) {
struct statsd_node *sn = (struct statsd_node *) uspi->data;
// reset the buffer
ub->pos = 0;
ub->pos = 0;
if (uwsgi_buffer_append(ub, sn->prefix, sn->prefix_len)) return -1;
if (uwsgi_buffer_append(ub, ".", 1)) return -1;
if (uwsgi_buffer_append(ub, metric, metric_len)) return -1;
if (uwsgi_buffer_append(ub, ":", 1)) return -1;
if (uwsgi_buffer_append(ub, ".worker", 7)) return -1;
if (uwsgi_buffer_num64(ub, wid)) return -1;
if (uwsgi_buffer_append(ub, ".", 1)) return -1;
if (uwsgi_buffer_append(ub, metric, metric_len)) return -1;
if (uwsgi_buffer_append(ub, ":", 1)) return -1;
if (uwsgi_buffer_num64(ub, value)) return -1;
if (uwsgi_buffer_append(ub, "|g", 2)) return -1;
if (sendto(sn->fd, ub->buf, ub->pos, 0, (struct sockaddr *) &sn->addr.sa_in, sn->addr_len) < 0) {
uwsgi_error("stats_pusher_statsd()/sendto()");
}
return 0;
}
static int statsd_send_core_gauge(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, int wid, int coreid, char *metric, uint16_t metric_len, int64_t value) {
struct statsd_node *sn = (struct statsd_node *) uspi->data;
// reset the buffer
ub->pos = 0;
if (uwsgi_buffer_append(ub, sn->prefix, sn->prefix_len)) return -1;
if (uwsgi_buffer_append(ub, ".worker", 7)) return -1;
if (uwsgi_buffer_num64(ub, wid)) return -1;
if (uwsgi_buffer_append(ub, ".core", 5)) return -1;
if (uwsgi_buffer_num64(ub, coreid)) return -1;
if (uwsgi_buffer_append(ub, ".", 1)) return -1;
if (uwsgi_buffer_append(ub, metric, metric_len)) return -1;
if (uwsgi_buffer_append(ub, ":", 1)) return -1;
if (uwsgi_buffer_num64(ub, value)) return -1;
if (uwsgi_buffer_append(ub, type, 2)) return -1;
if (uwsgi_buffer_append(ub, "|g", 2)) return -1;
if (sendto(sn->fd, ub->buf, ub->pos, 0, (struct sockaddr *) &sn->addr.sa_in, sn->addr_len) < 0) {
uwsgi_error("statsd_send_metric()/sendto()");
}
return 0;
if (sendto(sn->fd, ub->buf, ub->pos, 0, (struct sockaddr *) &sn->addr.sa_in, sn->addr_len) < 0) {
uwsgi_error("stats_pusher_statsd()/sendto()");
}
return 0;
}
@@ -84,19 +106,20 @@ static void stats_pusher_statsd(struct uwsgi_stats_pusher_instance *uspi, time_t
// we use the same buffer for all of the packets
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
struct uwsgi_metric *um = uwsgi.metrics;
while(um) {
uwsgi_rlock(uwsgi.metrics_lock);
// ignore return value
if (um->type == UWSGI_METRIC_GAUGE) {
statsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|g");
int i, j;
// send workers metrics
for(i=1;i<=uwsgi.numproc;i++) {
if (statsd_send_worker_gauge(ub, uspi, i, "requests", 8, uwsgi.workers[i].requests)) goto end;
for(j=0;j<uwsgi.cores;j++) {
if (statsd_send_core_gauge(ub, uspi, i, j, "exceptions", 10, uwsgi.workers[i].cores[j].exceptions)) goto end;
if (statsd_send_core_gauge(ub, uspi, i, j, "requests", 8, uwsgi.workers[i].cores[j].requests)) goto end;
if (statsd_send_core_gauge(ub, uspi, i, j, "routed_requests", 15, uwsgi.workers[i].cores[j].routed_requests)) goto end;
if (statsd_send_core_gauge(ub, uspi, i, j, "static_requests", 15, uwsgi.workers[i].cores[j].static_requests)) goto end;
if (statsd_send_core_gauge(ub, uspi, i, j, "offloaded_requests", 18, uwsgi.workers[i].cores[j].offloaded_requests)) goto end;
}
else {
statsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|m");
}
uwsgi_rwunlock(uwsgi.metrics_lock);
um = um->next;
}
end:
uwsgi_buffer_destroy(ub);
}
-414
View File
@@ -1,414 +0,0 @@
#include "../python/uwsgi_python.h"
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
struct uwsgi_tornado {
PyObject *ioloop;
PyObject *functools;
PyObject *request;
PyObject *read;
PyObject *write;
PyObject *hook_fd;
PyObject *hook_timeout;
PyObject *hook_fix;
} utornado;
#define free_req_queue uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req
static void uwsgi_opt_setup_tornado(char *opt, char *value, void *null) {
// set async mode
uwsgi_opt_set_int(opt, value, &uwsgi.async);
if (uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] < 30) {
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 30;
}
// set loop engine
uwsgi.loop = "tornado";
}
static struct uwsgi_option tornado_options[] = {
{"tornado", required_argument, 0, "a shortcut enabling tornado loop engine with the specified number of async cores and optimal parameters", uwsgi_opt_setup_tornado, NULL, UWSGI_OPT_THREADS},
{0, 0, 0, 0, 0, 0, 0},
};
static void gil_tornado_get() {
pthread_setspecific(up.upt_gil_key, (void *) PyGILState_Ensure());
}
static void gil_tornado_release() {
PyGILState_Release((PyGILState_STATE) pthread_getspecific(up.upt_gil_key));
}
static int uwsgi_tornado_wait_read_hook(int fd, int timeout) {
/*
def hook_fd(wsgi_req, fd, events):
uwsgi.resume(wsgi_req)
def hook_timeout(wsgi_req):
wsgi_req->timed_out = 1;
uwsgi.resume(wsgi_req)
io_loop.add_handler(fd, functools.partial(hook, wsgi_req), io_loop.READ)
t = io_loop.add_timeout(timeout, functools.partial(hook, wsgi_req))
uwsgi.suspend()
io_loop.remove_handler(fd)
io_loop.remove_timeout(t)
if wsgi_req->timed_out: return 0
*/
struct wsgi_request *wsgi_req = current_wsgi_req();
PyObject *cb_fd = PyObject_CallMethod(utornado.functools, "partial", "Ol", utornado.hook_fd, (long) wsgi_req);
if (!cb_fd) goto error;
PyObject *cb_timeout = PyObject_CallMethod(utornado.functools, "partial", "Ol", utornado.hook_timeout, (long) wsgi_req);
if (!cb_timeout) {
Py_DECREF(cb_fd);
goto error;
}
if (PyObject_CallMethod(utornado.ioloop, "add_handler", "iOO", fd, cb_fd, utornado.read) == NULL) {
Py_DECREF(cb_fd);
Py_DECREF(cb_timeout);
goto error;
}
PyObject *ob_timeout = PyObject_CallMethod(utornado.ioloop, "add_timeout", "iO", uwsgi_now() + timeout, cb_timeout);
if (!ob_timeout) {
Py_DECREF(cb_fd);
Py_DECREF(cb_timeout);
goto error;
}
// back to ioloop
if (uwsgi.schedule_to_main) uwsgi.schedule_to_main(wsgi_req);
// back from ioloop
if (PyObject_CallMethod(utornado.ioloop, "remove_handler", "i", fd) == NULL) PyErr_Print();
if (PyObject_CallMethod(utornado.ioloop, "remove_timeout", "O", ob_timeout) == NULL) PyErr_Print();
Py_DECREF(ob_timeout);
Py_DECREF(cb_fd);
Py_DECREF(cb_timeout);
if (wsgi_req->async_timed_out) return 0;
return 1;
error:
PyErr_Print();
return -1;
}
static int uwsgi_tornado_wait_write_hook(int fd, int timeout) {
struct wsgi_request *wsgi_req = current_wsgi_req();
PyObject *cb_fd = PyObject_CallMethod(utornado.functools, "partial", "Ol", utornado.hook_fd, (long) wsgi_req);
if (!cb_fd) goto error;
PyObject *cb_timeout = PyObject_CallMethod(utornado.functools, "partial", "Ol", utornado.hook_timeout, (long) wsgi_req);
if (!cb_timeout) {
Py_DECREF(cb_fd);
goto error;
}
if (PyObject_CallMethod(utornado.ioloop, "add_handler", "iOO", fd, cb_fd, utornado.write) == NULL) {
Py_DECREF(cb_fd);
Py_DECREF(cb_timeout);
goto error;
}
PyObject *ob_timeout = PyObject_CallMethod(utornado.ioloop, "add_timeout", "iO", uwsgi_now() + timeout, cb_timeout);
if (!ob_timeout) {
Py_DECREF(cb_fd);
Py_DECREF(cb_timeout);
goto error;
}
// back to ioloop
if (uwsgi.schedule_to_main) {
uwsgi.schedule_to_main(wsgi_req);
}
// back from ioloop
if (PyObject_CallMethod(utornado.ioloop, "remove_handler", "i", fd) == NULL) PyErr_Print();
if (PyObject_CallMethod(utornado.ioloop, "remove_timeout", "O", ob_timeout) == NULL) PyErr_Print();
Py_DECREF(ob_timeout);
Py_DECREF(cb_fd);
Py_DECREF(cb_timeout);
if (wsgi_req->async_timed_out) return 0;
return 1;
error:
PyErr_Print();
return -1;
}
PyObject *py_uwsgi_tornado_request(PyObject *self, PyObject *args) {
int fd = -1;
PyObject *events = NULL;
if (!PyArg_ParseTuple(args, "iO:uwsgi_tornado_request", &fd, &events)) {
uwsgi_log_verbose("[BUG] invalid arguments for tornado callback !!!\n");
exit(1);
}
struct wsgi_request *wsgi_req = find_wsgi_req_proto_by_fd(fd);
uwsgi.wsgi_req = wsgi_req;
int status = wsgi_req->socket->proto(wsgi_req);
if (status > 0) goto again;
if (PyObject_CallMethod(utornado.ioloop, "remove_handler", "i", fd) == NULL) {
PyErr_Print();
goto end;
}
if (status == 0) {
// we call this two time... overengineering :(
uwsgi.async_proto_fd_table[wsgi_req->fd] = NULL;
uwsgi.schedule_to_req();
goto again;
}
end:
uwsgi.async_proto_fd_table[wsgi_req->fd] = NULL;
uwsgi_close_request(uwsgi.wsgi_req);
free_req_queue;
again:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_tornado_accept(PyObject *self, PyObject *args) {
int fd = -1;
PyObject *events = NULL;
if (!PyArg_ParseTuple(args, "iO:uwsgi_tornado_accept", &fd, &events)) {
return NULL;
}
struct wsgi_request *wsgi_req = find_first_available_wsgi_req();
if (wsgi_req == NULL) {
uwsgi_async_queue_is_full(uwsgi_now());
goto end;
}
uwsgi.wsgi_req = wsgi_req;
// TODO better to move it to a function api ...
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
if (uwsgi_sock->fd == fd) break;
uwsgi_sock = uwsgi_sock->next;
}
if (!uwsgi_sock) {
free_req_queue;
goto end;
}
// fill wsgi_request structure
wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock );
// mark core as used
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1;
// accept the connection (since uWSGI 1.5 all of the sockets are non-blocking)
if (wsgi_req_simple_accept(wsgi_req, uwsgi_sock->fd)) {
// in case of errors (or thundering herd, just reset it)
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 0;
free_req_queue;
goto end;
}
wsgi_req->start_of_request = uwsgi_micros();
wsgi_req->start_of_request_in_sec = wsgi_req->start_of_request/1000000;
// enter harakiri mode
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
}
uwsgi.async_proto_fd_table[wsgi_req->fd] = wsgi_req;
// add callback for protocol
if (PyObject_CallMethod(utornado.ioloop, "add_handler", "iOO", wsgi_req->fd, utornado.request, utornado.read) == NULL) {
free_req_queue;
PyErr_Print();
}
end:
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_tornado_hook_fd(PyObject *self, PyObject *args) {
long wsgi_req_ptr = 0;
int fd = -1;
PyObject *events = NULL;
if (!PyArg_ParseTuple(args, "liO:uwsgi_tornado_hook_fd", &wsgi_req_ptr, &fd, &events)) {
return NULL;
}
uwsgi.wsgi_req = (struct wsgi_request *) wsgi_req_ptr;
uwsgi.schedule_to_req();
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_tornado_hook_timeout(PyObject *self, PyObject *args) {
long wsgi_req_ptr = 0;
if (!PyArg_ParseTuple(args, "l", &wsgi_req_ptr)) {
return NULL;
}
uwsgi.wsgi_req = (struct wsgi_request *) wsgi_req_ptr;
uwsgi.wsgi_req->async_timed_out = 1;
uwsgi.schedule_to_req();
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_tornado_hook_fix(PyObject *self, PyObject *args) {
long wsgi_req_ptr = 0;
if (!PyArg_ParseTuple(args, "l", &wsgi_req_ptr)) {
return NULL;
}
uwsgi.wsgi_req = (struct wsgi_request *) wsgi_req_ptr;
uwsgi.schedule_to_req();
Py_INCREF(Py_None);
return Py_None;
}
PyMethodDef uwsgi_tornado_accept_def[] = { {"uwsgi_tornado_accept", py_uwsgi_tornado_accept, METH_VARARGS, ""} };
PyMethodDef uwsgi_tornado_request_def[] = { {"uwsgi_tornado_request", py_uwsgi_tornado_request, METH_VARARGS, ""} };
PyMethodDef uwsgi_tornado_hook_fd_def[] = { {"uwsgi_tornado_hook_fd", py_uwsgi_tornado_hook_fd, METH_VARARGS, ""} };
PyMethodDef uwsgi_tornado_hook_timeout_def[] = { {"uwsgi_tornado_hook_timeout", py_uwsgi_tornado_hook_timeout, METH_VARARGS, ""} };
PyMethodDef uwsgi_tornado_hook_fix_def[] = { {"uwsgi_tornado_hook_fix", py_uwsgi_tornado_hook_fix, METH_VARARGS, ""} };
static void uwsgi_tornado_schedule_fix(struct wsgi_request *wsgi_req) {
PyObject *cb_fix = PyObject_CallMethod(utornado.functools, "partial", "Ol", utornado.hook_fix, (long) wsgi_req);
if (!cb_fix) goto error;
if (PyObject_CallMethod(utornado.ioloop, "add_callback", "O", cb_fix) == NULL) {
Py_DECREF(cb_fix);
goto error;
}
Py_DECREF(cb_fix);
return;
error:
PyErr_Print();
}
static void tornado_loop() {
if (!uwsgi.has_threads && uwsgi.mywid == 1) {
uwsgi_log("!!! Running tornado without threads IS NOT recommended, enable them with --enable-threads !!!\n");
}
if (uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] < 30) {
uwsgi_log("!!! Running tornado with a socket-timeout lower than 30 seconds is not recommended, tune it with --socket-timeout !!!\n");
}
// get the GIL
UWSGI_GET_GIL
up.gil_get = gil_tornado_get;
up.gil_release = gil_tornado_release;
uwsgi.wait_write_hook = uwsgi_tornado_wait_write_hook;
uwsgi.wait_read_hook = uwsgi_tornado_wait_read_hook;
uwsgi.schedule_fix = uwsgi_tornado_schedule_fix;
if (uwsgi.async < 2) {
uwsgi_log("the tornado loop engine requires async mode (--async <n>)\n");
exit(1);
}
if (!uwsgi.schedule_to_main) {
uwsgi_log("*** DANGER *** tornado mode without coroutine/greenthread engine loaded !!!\n");
}
PyObject *tornado_dict = get_uwsgi_pydict("tornado.ioloop");
if (!tornado_dict) uwsgi_pyexit;
PyObject *tornado_IOLoop = PyDict_GetItemString(tornado_dict, "IOLoop");
if (!tornado_IOLoop) uwsgi_pyexit;
utornado.ioloop = PyObject_CallMethod(tornado_IOLoop, "instance", NULL);
if (!utornado.ioloop) uwsgi_pyexit;
// main greenlet waiting for connection (one greenlet per-socket)
PyObject *uwsgi_tornado_accept = PyCFunction_New(uwsgi_tornado_accept_def, NULL);
Py_INCREF(uwsgi_tornado_accept);
utornado.request = PyCFunction_New(uwsgi_tornado_request_def, NULL);
if (!utornado.request) uwsgi_pyexit;
utornado.hook_fd = PyCFunction_New(uwsgi_tornado_hook_fd_def, NULL);
if (!utornado.hook_fd) uwsgi_pyexit;
utornado.hook_timeout = PyCFunction_New(uwsgi_tornado_hook_timeout_def, NULL);
if (!utornado.hook_timeout) uwsgi_pyexit;
utornado.hook_fix = PyCFunction_New(uwsgi_tornado_hook_fix_def, NULL);
if (!utornado.hook_fix) uwsgi_pyexit;
utornado.read = PyObject_GetAttrString(utornado.ioloop, "READ");
if (!utornado.read) uwsgi_pyexit;
utornado.write = PyObject_GetAttrString(utornado.ioloop, "WRITE");
if (!utornado.write) uwsgi_pyexit;
utornado.functools = PyImport_ImportModule("functools");
if (!utornado.functools) uwsgi_pyexit;
Py_INCREF(utornado.request);
Py_INCREF(utornado.hook_fd);
Py_INCREF(utornado.hook_timeout);
Py_INCREF(utornado.hook_fix);
Py_INCREF(utornado.read);
Py_INCREF(utornado.write);
// call add_handler on each socket
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
if (PyObject_CallMethod(utornado.ioloop, "add_handler", "iOO", uwsgi_sock->fd, uwsgi_tornado_accept, utornado.read) == NULL) {
uwsgi_pyexit;
}
uwsgi_sock = uwsgi_sock->next;
}
if (PyObject_CallMethod(utornado.ioloop, "start", NULL) == NULL) {
uwsgi_pyexit;
}
// never here ?
}
static void tornado_init() {
uwsgi_register_loop( (char *) "tornado", tornado_loop);
}
struct uwsgi_plugin tornado_plugin = {
.name = "tornado",
.options = tornado_options,
.on_load = tornado_init,
};
-8
View File
@@ -1,8 +0,0 @@
from distutils import sysconfig
NAME='tornado'
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
LDFLAGS = []
LIBS = []
GCC_LIST = ['tornado']
-42
View File
@@ -1,42 +0,0 @@
#include <uwsgi.h>
#ifdef UWSGI_ROUTING
// apply templating
static int transform_template(struct wsgi_request *wsgi_req, struct uwsgi_transformation *ut) {
struct uwsgi_route *ur = (struct uwsgi_route *) ut->data;
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ut->chunk->buf, ut->chunk->pos);
if (!ub) return -1;
uwsgi_buffer_map(ut->chunk, ub->buf, ub->pos);
ub->buf = NULL;
uwsgi_buffer_destroy(ub);
return 0;
}
static int uwsgi_router_template_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
uwsgi_add_transformation(wsgi_req, transform_template, route);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_template(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_template_func;
return 0;
}
static void transformation_template_register(void) {
uwsgi_register_router("template", uwsgi_router_template);
}
struct uwsgi_plugin transformation_template_plugin = {
.name = "transformation_template",
.on_load = transformation_template_register,
};
#else
struct uwsgi_plugin transformation_template_plugin = {
.name = "transformation_template",
};
#endif
@@ -1,6 +0,0 @@
NAME='transformation_template'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['tt']
+1 -1
View File
@@ -152,8 +152,8 @@ static v8::Handle < v8::Value > uwsgi_v8_commonjs_require(const v8::Arguments &
free(tmp_filename);
return ret;
}
free(tmp_filename);
}
free(tmp_filename);
usl = usl->next;
}
}
+6 -6
View File
@@ -92,9 +92,9 @@ static char *uwsgi_xslt_apply(xmlDoc *doc, char *xsltfile, char *params, int *rl
if (!ss) {
if (vparams) {
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
free(tmp_params);
free(vparams);
}
free(tmp_params);
return NULL;
}
@@ -103,9 +103,9 @@ static char *uwsgi_xslt_apply(xmlDoc *doc, char *xsltfile, char *params, int *rl
xsltFreeStylesheet(ss);
if (vparams) {
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
free(tmp_params);
free(vparams);
}
free(tmp_params);
return NULL;
}
@@ -115,9 +115,9 @@ static char *uwsgi_xslt_apply(xmlDoc *doc, char *xsltfile, char *params, int *rl
xmlFreeDoc(res);
if (vparams) {
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
free(tmp_params);
free(vparams);
}
free(tmp_params);
if (ret < 0) return NULL;
return (char *) output;
}
@@ -183,9 +183,10 @@ static int uwsgi_request_xslt(struct wsgi_request *wsgi_req) {
return UWSGI_OK;
}
free(xmlfile);
if (!uwsgi_is_file(filename)) {
uwsgi_403(wsgi_req);
free(xmlfile);
return UWSGI_OK;
}
filename_len = strlen(filename);
@@ -275,7 +276,6 @@ apply:
}
// we have both the file and the stylesheet, let's run the engine
xmlDoc *doc = xmlParseFile(xmlfile);
free(xmlfile);
if (!doc) {
uwsgi_500(wsgi_req);
return UWSGI_OK;
@@ -441,7 +441,7 @@ static int uwsgi_router_xslt(struct uwsgi_route *ur, char *args) {
exit(1);
}
if (!urxc->doc || !urxc->stylesheet) {
if (!urxc->doc && !urxc->stylesheet) {
uwsgi_log("invalid route syntax: you need to specify a doc and a stylesheet\n");
exit(1);
}
-198
View File
@@ -1,198 +0,0 @@
#include <uwsgi.h>
/*
this is a stats pusher plugin for the zabbix server:
--stats-push zabbix:address[,prefix]
example:
--stats-push zabbix:127.0.0.1:10051,myinstance
it exports values exposed by the metric subsystem
*/
extern struct uwsgi_server uwsgi;
static char *zabbix_template = NULL;
static void uwsgi_opt_zabbix_template(char *opt, char *value, void *none) {
if (value) {
zabbix_template = value;
}
else {
zabbix_template = "";
}
}
static struct uwsgi_option zabbix_options[] = {
{"zabbix-template", optional_argument, 0, "print (or store to a file) the zabbix template for the current metrics setup", uwsgi_opt_zabbix_template, NULL, UWSGI_OPT_METRICS},
{0, 0, 0, 0, 0, 0, 0},
};
// configuration of a zabbix node
struct zabbix_node {
char *addr;
char *prefix;
uint16_t prefix_len;
// we reuse the same buffer
struct uwsgi_buffer *ub;
};
/*
{
"request":"sender data",
"data": [
{"host":uwsgi.hostname, "key":"foo", "value":"bar"},
...
]
}
*/
static void stats_pusher_zabbix(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
if (!uspi->configured) {
struct zabbix_node *zn = uwsgi_calloc(sizeof(struct zabbix_node));
if (!uspi->arg || strlen(uspi->arg) == 0) {
zn->addr = uwsgi_str("127.0.0.1:10051");
}
else {
zn->addr = uwsgi_str(uspi->arg);
}
char *comma = strchr(zn->addr, ',');
if (comma) {
zn->prefix = comma+1;
zn->prefix_len = strlen(zn->prefix);
*comma = 0;
}
else {
zn->prefix = "uwsgi";
zn->prefix_len = 5;
}
zn->ub = uwsgi_buffer_new(uwsgi.page_size);
uwsgi_buffer_append(zn->ub, "ZBXD\1\0\0\0\0\0\0\0\0{\"request\":\"sender data\",\"data\":[", 46);
uspi->data = zn;
uspi->configured = 1;
}
struct zabbix_node *zn = (struct zabbix_node *) uspi->data ;
// we use the same buffer for all of the packets
zn->ub->pos = 46;
struct uwsgi_metric *um = uwsgi.metrics;
int error = 0;
uwsgi_rlock(uwsgi.metrics_lock);
while(um) {
if (uwsgi_buffer_append(zn->ub, "{\"host\":\"", 9)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, uwsgi.hostname, uwsgi.hostname_len)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, "\",\"key\":\"", 9)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, zn->prefix, zn->prefix_len)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, ".", 1)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, um->name, um->name_len)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, "\",\"value\":\"", 11)) { error = 1; goto end;}
if (uwsgi_buffer_num64(zn->ub, *um->value)) { error = 1; goto end;}
if (uwsgi_buffer_append(zn->ub, "\"}", 2)) { error = 1; goto end;}
um = um->next;
if (um) {
if (uwsgi_buffer_append(zn->ub, ",", 1)) { error = 1; goto end;}
}
}
if (uwsgi_buffer_append(zn->ub, "]}", 2)) error = 1;
end:
uwsgi_rwunlock(uwsgi.metrics_lock);
if (error) return;
uint64_t pktsize = zn->ub->pos - 13;
zn->ub->pos = 5;
if (uwsgi_buffer_u64le(zn->ub, pktsize)) error = 1;
if (error) return;
int fd = uwsgi_connect(zn->addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
if (fd < 0) {
uwsgi_error("stats_pusher_zabbix()/connect()");
return;
}
if (write(fd, zn->ub->buf, pktsize + 13) != (ssize_t) (pktsize + 13)) {
uwsgi_error("stats_pusher_zabbix()/write()");
}
// fake read for simplify debug with strace
char buf[4096];
if (read(fd, buf, 4096) <= 0) {
uwsgi_error("stats_pusher_zabbix()/read()");
}
close(fd);
}
static void stats_pusher_zabbix_init(void) {
struct uwsgi_stats_pusher *usp = uwsgi_register_stats_pusher("zabbix", stats_pusher_zabbix);
// we use a custom format not the JSON one
usp->raw = 1;
}
static void zabbix_template_print() {
if (!zabbix_template) return;
int fd = 1 ;
if (zabbix_template[0] != 0) {
fd = open(zabbix_template, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP);
if (fd < 0) {
uwsgi_error_open(zabbix_template);
exit(1);
}
}
struct uwsgi_metric *um = uwsgi.metrics;
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
if (uwsgi_buffer_append(ub,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", 39)) goto error;
if (uwsgi_buffer_append(ub,"<zabbix_export>\n", 16)) goto error;
if (uwsgi_buffer_append(ub,"<version>2.0</version><groups><group><name>uWSGI</name></group></groups>\n", 73)) goto error;
if (uwsgi_buffer_append(ub,"\t<templates><template><template>uWSGI metrics</template><name>uWSGI metrics</name>\n", 83)) goto error;
if (uwsgi_buffer_append(ub,"\t<groups><group><name>uWSGI</name></group></groups>\n", 52)) goto error;
if (uwsgi_buffer_append(ub,"\t<items>\n", 9)) goto error;
while(um) {
if (uwsgi_buffer_append(ub,"\t\t<item>\n", 9)) goto error;
if (uwsgi_buffer_append(ub,"\t\t\t<name>", 9)) goto error;
if (uwsgi_buffer_append(ub, um->name, um->name_len)) goto error;
if (uwsgi_buffer_append(ub,"</name>\n", 8)) goto error;
if (uwsgi_buffer_append(ub,"\t\t\t<type>2</type>\n", 18)) goto error;
if (uwsgi_buffer_append(ub,"\t\t\t<key>", 8)) goto error;
if (uwsgi_buffer_append(ub, um->name, um->name_len)) goto error;
if (uwsgi_buffer_append(ub,"</key>\n", 7)) goto error;
if (uwsgi_buffer_append(ub,"\t\t\t<value_type>3</value_type>\n", 30)) goto error;
if (uwsgi_buffer_append(ub,"\t\t</item>\n", 10)) goto error;
um = um->next;
}
if (uwsgi_buffer_append(ub,"\t</items></template></templates>\n", 33)) goto error;
if (uwsgi_buffer_append(ub,"</zabbix_export>\n", 17)) goto error;
if (write(fd, ub->buf, ub->pos) != (ssize_t) ub->pos) {
uwsgi_error("zabbix_template_print()/wrtie()");
exit(1);
}
uwsgi_buffer_destroy(ub);
if (zabbix_template[0] != 0) {
uwsgi_log("zabbix template written to %s\n", zabbix_template);
close(fd);
}
return;
error:
uwsgi_buffer_destroy(ub);
uwsgi_log("error generating zabbix template\n");
exit(1);
}
struct uwsgi_plugin zabbix_plugin = {
.name = "zabbix",
.options = zabbix_options,
.on_load = stats_pusher_zabbix_init,
.preinit_apps = zabbix_template_print,
};
-7
View File
@@ -1,7 +0,0 @@
NAME='zabbix'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['plugin']
-5
View File
@@ -219,8 +219,3 @@ ssize_t uwsgi_proto_base_read_body(struct wsgi_request *wsgi_req, char *buf, siz
}
return read(wsgi_req->fd, buf, len);
}
ssize_t uwsgi_proto_noop_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
uwsgi_log_verbose("!!! the current protocol does not support request body !!!\n");
return -1;
}
-91
View File
@@ -1,91 +0,0 @@
/* async uwsgi protocol parser */
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
/*
perfect framing is required in persistent mode, so we need at least 2 syscall to assemble
a uwsgi header: 4 bytes header + payload
increase write_errors on error to force socket close
*/
int uwsgi_proto_puwsgi_parser(struct wsgi_request *wsgi_req) {
ssize_t len;
char *ptr = (char *) wsgi_req->uh;
if (wsgi_req->proto_parser_pos < 4) {
len = read(wsgi_req->fd, ptr + wsgi_req->proto_parser_pos, 4 - wsgi_req->proto_parser_pos);
if (len > 0) {
wsgi_req->proto_parser_pos += len;
if (wsgi_req->proto_parser_pos == 4) {
#ifdef __BIG_ENDIAN__
wsgi_req->uh->pktsize = uwsgi_swap16(wsgi_req->uh->pktsize);
#endif
if (wsgi_req->uh->pktsize > uwsgi.buffer_size) {
uwsgi_log("invalid request block size: %u (max %u)...skip\n", wsgi_req->uh->pktsize, uwsgi.buffer_size);
wsgi_req->write_errors++;
return -1;
}
}
return UWSGI_AGAIN;
}
goto negative;
}
len = read(wsgi_req->fd, ptr + wsgi_req->proto_parser_pos, wsgi_req->uh->pktsize - (wsgi_req->proto_parser_pos-4));
if (len > 0) {
wsgi_req->proto_parser_pos += len;
if ((wsgi_req->proto_parser_pos-4) == wsgi_req->uh->pktsize) {
return UWSGI_OK;
}
return UWSGI_AGAIN;
}
negative:
if (len < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
return UWSGI_AGAIN;
}
uwsgi_error("uwsgi_proto_uwsgi_parser()");
wsgi_req->write_errors++;
return -1;
}
// 0 len
if (wsgi_req->proto_parser_pos > 0) {
uwsgi_error("uwsgi_proto_uwsgi_parser()");
}
wsgi_req->write_errors++;
return -1;
}
/*
close the connection on errors, otherwise force edge triggering
*/
void uwsgi_proto_puwsgi_close(struct wsgi_request *wsgi_req) {
// check for errors or incomplete packets
if (wsgi_req->write_errors || (size_t) (wsgi_req->uh->pktsize + 4) != wsgi_req->proto_parser_pos) {
close(wsgi_req->fd);
wsgi_req->socket->retry[wsgi_req->async_id] = 0;
wsgi_req->socket->fd_threads[wsgi_req->async_id] = -1;
}
else {
wsgi_req->socket->retry[wsgi_req->async_id] = 1;
wsgi_req->socket->fd_threads[wsgi_req->async_id] = wsgi_req->fd;
}
}
int uwsgi_proto_puwsgi_accept(struct wsgi_request *wsgi_req, int fd) {
if (wsgi_req->socket->retry[wsgi_req->async_id]) {
wsgi_req->fd = wsgi_req->socket->fd_threads[wsgi_req->async_id];
int ret = uwsgi_wait_read_req(wsgi_req);
if (ret <= 0) {
close(wsgi_req->fd);
wsgi_req->socket->retry[wsgi_req->async_id] = 0;
wsgi_req->socket->fd_threads[wsgi_req->async_id] = -1;
return -1;
}
return wsgi_req->socket->fd_threads[wsgi_req->async_id];
}
return uwsgi_proto_base_accept(wsgi_req, fd);
}
+108
View File
@@ -0,0 +1,108 @@
/* async uwsgi protocol parser */
#include "../uwsgi.h"
extern struct uwsgi_server uwsgi;
#define PROTO_STATUS_RECV_HDR 0
#define PROTO_STATUS_RECV_VARS 1
int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) {
uint8_t *hdr_buf = (uint8_t *) & wsgi_req->uh;
ssize_t len;
struct iovec iov[1];
struct cmsghdr *cmsg;
if (wsgi_req->proto_parser_status == PROTO_STATUS_RECV_HDR) {
if (wsgi_req->proto_parser_pos > 0) {
len = read(wsgi_req->poll.fd, hdr_buf + wsgi_req->proto_parser_pos, 4 - wsgi_req->proto_parser_pos);
}
else {
iov[0].iov_base = hdr_buf;
iov[0].iov_len = 4;
wsgi_req->msg.msg_name = NULL;
wsgi_req->msg.msg_namelen = 0;
wsgi_req->msg.msg_iov = iov;
wsgi_req->msg.msg_iovlen = 1;
wsgi_req->msg.msg_control = &wsgi_req->msg_control;
wsgi_req->msg.msg_controllen = sizeof(wsgi_req->msg_control);
wsgi_req->msg.msg_flags = 0;
len = recvmsg(wsgi_req->poll.fd, &wsgi_req->msg, 0);
}
if (len <= 0) {
uwsgi_error("read()");
return -1;
}
wsgi_req->proto_parser_pos += len;
// header ready ?
if (wsgi_req->proto_parser_pos == 4) {
wsgi_req->proto_parser_status = PROTO_STATUS_RECV_VARS;
wsgi_req->proto_parser_pos = 0;
/* big endian ? */
#ifdef __BIG_ENDIAN__
wsgi_req->uh.pktsize = uwsgi_swap16(wsgi_req->uh.pktsize);
#endif
uwsgi_debug("uwsgi payload size: %d (0x%X) modifier1: %d modifier2: %d\n", wsgi_req->uh.pktsize, wsgi_req->uh.pktsize, wsgi_req->uh.modifier1, wsgi_req->uh.modifier2);
/* check for max buffer size */
if (wsgi_req->uh.pktsize > uwsgi.buffer_size) {
uwsgi_log("invalid request block size. requested %d bytes available %d bytes...skip\n", wsgi_req->uh.pktsize, uwsgi.buffer_size);
return -1;
}
if (!wsgi_req->uh.pktsize)
return UWSGI_OK;
}
return UWSGI_AGAIN;
}
else if (wsgi_req->proto_parser_status == PROTO_STATUS_RECV_VARS) {
len = read(wsgi_req->poll.fd, wsgi_req->buffer + wsgi_req->proto_parser_pos, wsgi_req->uh.pktsize - wsgi_req->proto_parser_pos);
if (len <= 0) {
uwsgi_error("read()");
return -1;
}
wsgi_req->proto_parser_pos += len;
// body ready ?
if (wsgi_req->proto_parser_pos >= wsgi_req->uh.pktsize) {
// older OSX versions make mess with CMSG_FIRSTHDR
#ifdef __APPLE__
if (!wsgi_req->msg.msg_controllen)
return UWSGI_OK;
#endif
cmsg = CMSG_FIRSTHDR(&wsgi_req->msg);
while (cmsg != NULL) {
if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type && SCM_RIGHTS) {
// upgrade connection to the new socket
uwsgi_log("upgrading fd %d to ", wsgi_req->poll.fd);
close(wsgi_req->poll.fd);
memcpy(&wsgi_req->poll.fd, CMSG_DATA(cmsg), sizeof(int));
uwsgi_log("%d\n", wsgi_req->poll.fd);
}
cmsg = CMSG_NXTHDR(&wsgi_req->msg, cmsg);
}
return UWSGI_OK;
}
return UWSGI_AGAIN;
}
// never here
return -1;
}
-53
View File
@@ -1,53 +0,0 @@
#!/usr/bin/perl
#uwsgi --http-socket :9090 --route-run "send:\${PATH_INFO}"
use IO::Socket::INET;
my @tests;
push @tests, ['/foo','/foo'];
push @tests, ['./foo','/foo'];
push @tests, ['./foo/bar?a=1','/foo/bar'];
push @tests, ['//foo/bar','//foo/bar'];
push @tests, ['foo/bar','foo/bar'];
push @tests, ['foo/bar/../','foo/'];
push @tests, ['foo/bar/..','foo/'];
push @tests, ['/foo/bar/..','/foo/'];
push @tests, ['../../../foo/bar/..','/foo/'];
push @tests, ['test1/test2/../test3/','test1/test3/'];
push @tests, ['t#est1/test2/../test3/','t'];
push @tests, ['/one/two/three/four/../five','/one/two/three/five'];
push @tests, ['/one/two/three/four/../../five','/one/two/five'];
push @tests, ['/one/two/three/four/../../five/','/one/two/five/'];
push @tests, ['/one/two/three/four/../../five/..','/one/two/'];
push @tests, ['.one/two/three/four/../../five/..','.one/two/'];
push @tests, ['..one/two/three/four/../../five/..','..one/two/'];
push @tests, ['/../','/'];
push @tests, ['../','/'];
push @tests, ['/.','/'];
push @tests, ['..one/two/three/four/../../../../../five/..','/'];
push @tests, ['./foo/.bar.','/foo/.bar.'];
foreach(@tests) {
print "testing: ".$_->[0]."\n";
my $req = "GET ".$_->[0]." HTTP/1.0\r\n\r\n";
my $s = IO::Socket::INET->new(PeerAddr => $ARGV[0]);
$s->send($req);
my $response = '';
while(1) {
$s->recv(my $buf, 4096);
last unless length($buf);
$response .= $buf;
}
$s->close;
if ($response ne $_->[1]) {
print "TEST FOR ".$_->[0]." FAILED: EXPECTED ".$_->[1]." GOT ".$response."\n";
exit;
}
}
print "test result: SUCCESS\n";
+5 -18
View File
@@ -5,7 +5,6 @@
import uwsgi
import time
import redis
import sys
def application(env, sr):
@@ -15,7 +14,7 @@ def application(env, sr):
if env['PATH_INFO'] == '/':
sr('200 OK', [('Content-Type','text/html')])
output = """
return """
<html>
<head>
<script language="Javascript">
@@ -53,14 +52,11 @@ def application(env, sr):
</body>
</html>
""" % (ws_scheme, env['HTTP_HOST'])
if sys.version_info[0] > 2:
return output.encode('latin1')
return output
elif env['PATH_INFO'] == '/favicon.ico':
return ""
elif env['PATH_INFO'] == '/foobar/':
uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
print("websockets...")
uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
print "websockets..."
r = redis.StrictRedis(host='localhost', port=6379, db=0)
channel = r.pubsub()
channel.subscribe('foobar')
@@ -69,7 +65,7 @@ def application(env, sr):
redis_fd = channel.connection._sock.fileno()
while True:
uwsgi.wait_fd_read(websocket_fd, 3)
uwsgi.wait_fd_read(websocket_fd)
uwsgi.wait_fd_read(redis_fd)
uwsgi.suspend()
fd = uwsgi.ready_fd()
@@ -80,15 +76,6 @@ def application(env, sr):
r.publish('foobar', msg)
elif fd == redis_fd:
msg = channel.parse_response()
print(msg)
# only interested in user messages
t = 'message'
if sys.version_info[0] > 2:
t = b'message'
if msg[0] == t:
if msg[0] == 'message':
uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
else:
# on timeout call websocket_recv_nb again to manage ping/pong
msg = uwsgi.websocket_recv_nb()
if msg:
r.publish('foobar', msg)
+1 -1
View File
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
s.name = 'uwsgi'
s.license = 'GPL-2'
s.version = `python -c "import uwsgiconfig as uc; print uc.uwsgi_version"`.sub(/-dev-.*/,'')
s.date = '2013-11-09'
s.date = '2013-10-11'
s.summary = "uWSGI"
s.description = "The uWSGI server for Ruby/Rack"
s.authors = ["Unbit"]
+7 -152
View File
@@ -72,7 +72,6 @@ extern "C" {
#define UWSGI_OPT_CLUSTER (1 << 12)
#define UWSGI_OPT_MIME (1 << 13)
#define UWSGI_OPT_REQ_LOG_MASTER (1 << 14)
#define UWSGI_OPT_METRICS (1 << 15)
#define MAX_GENERIC_PLUGINS 64
#define MAX_GATEWAYS 64
@@ -1618,8 +1617,6 @@ void uwsgi_opt_load_config(char *, char *, void *);
#define exit(x) uwsgi_exit(x)
struct uwsgi_metric;
struct uwsgi_server {
// store the machine hostname
@@ -1805,7 +1802,6 @@ struct uwsgi_server {
struct uwsgi_string_list *vassals_includes;
struct uwsgi_string_list *vassals_templates_before;
struct uwsgi_string_list *vassals_includes_before;
struct uwsgi_string_list *vassals_set;
// true if loyal to the emperor
int loyal;
@@ -1974,7 +1970,7 @@ struct uwsgi_server {
int log_reopen;
int log_truncate;
uint64_t log_maxsize;
off_t log_maxsize;
char *log_backupname;
int original_log_fd;
@@ -2438,7 +2434,6 @@ struct uwsgi_server {
// usedby suspend/resume loops
void (*schedule_to_main) (struct wsgi_request *);
void (*schedule_to_req) (void);
void (*schedule_fix) (struct wsgi_request *);
void (*gbcw_hook) (void);
@@ -2509,7 +2504,6 @@ struct uwsgi_server {
struct uwsgi_lock_item *cron_table_lock;
struct uwsgi_lock_item *rpc_table_lock;
struct uwsgi_lock_item *sa_lock;
struct uwsgi_lock_item *metrics_lock;
// rpc
uint64_t rpc_max;
@@ -2572,15 +2566,6 @@ struct uwsgi_server {
int chunked_input_timeout;
uint64_t chunked_input_limit;
struct uwsgi_metric *metrics;
struct uwsgi_metric_collector *metric_collectors;
int has_metrics;
char *metrics_dir;
int metrics_dir_restore;
uint64_t metrics_cnt;
struct uwsgi_string_list *additional_metrics;
struct uwsgi_string_list *metrics_threshold;
int (*wait_write_hook) (int, int);
int (*wait_read_hook) (int, int);
@@ -2603,13 +2588,6 @@ struct uwsgi_signal_entry {
void *handler;
};
/*
they are here for backwards compatibility
*/
#define SNMP_COUNTER32 0x41
#define SNMP_GAUGE 0x42
#define SNMP_COUNTER64 0x46
struct uwsgi_snmp_custom_value {
uint8_t type;
uint64_t val;
@@ -2665,6 +2643,10 @@ struct uwsgi_shared {
struct uwsgi_snmp_server_value snmp_gvalue[100];
struct uwsgi_snmp_custom_value snmp_value[100];
#define SNMP_COUNTER32 0x41
#define SNMP_GAUGE 0x42
#define SNMP_COUNTER64 0x46
int worker_signal_pipe[2];
int spooler_frequency;
int spooler_signal_pipe[2];
@@ -2702,13 +2684,6 @@ struct uwsgi_shared {
int gateways_cnt;
time_t gateways_harakiri[MAX_GATEWAYS];
uint64_t routed_signals;
uint64_t unrouted_signals;
uint64_t busy_workers;
uint64_t idle_workers;
uint64_t overloaded;
int ready;
};
@@ -3226,11 +3201,9 @@ size_t uwsgi_str_num(char *, int);
size_t uwsgi_str_occurence(char *, size_t, char);
int uwsgi_proto_uwsgi_parser(struct wsgi_request *);
int uwsgi_proto_puwsgi_parser(struct wsgi_request *);
int uwsgi_proto_base_write(struct wsgi_request *, char *, size_t);
int uwsgi_proto_base_write_header(struct wsgi_request *, char *, size_t);
ssize_t uwsgi_proto_base_read_body(struct wsgi_request *, char *, size_t);
ssize_t uwsgi_proto_noop_read_body(struct wsgi_request *, char *, size_t);
int uwsgi_proto_http_parser(struct wsgi_request *);
@@ -3245,10 +3218,8 @@ int uwsgi_proto_scgi_parser(struct wsgi_request *);
int uwsgi_proto_base_accept(struct wsgi_request *, int);
int uwsgi_proto_puwsgi_accept(struct wsgi_request *, int);
int uwsgi_proto_raw_parser(struct wsgi_request *);
void uwsgi_proto_base_close(struct wsgi_request *);
void uwsgi_proto_puwsgi_close(struct wsgi_request *);
uint16_t proto_base_add_uwsgi_header(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
uint16_t proto_base_add_uwsgi_var(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
@@ -3732,18 +3703,13 @@ struct uwsgi_stats_pusher_instance {
int configured;
int freq;
time_t last_run;
// retries
int needs_retry;
int retries;
int max_retries;
int retry_delay;
time_t next_retry;
struct uwsgi_stats_pusher_instance *next;
};
struct uwsgi_thread;
void uwsgi_stats_pusher_loop(struct uwsgi_thread *);
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
void uwsgi_stats_pusher_socket(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
void uwsgi_stats_pusher_setup(void);
void uwsgi_send_stats(int, struct uwsgi_stats *(*func) (void));
@@ -3938,7 +3904,6 @@ int uwsgi_buffer_u16le(struct uwsgi_buffer *, uint16_t);
int uwsgi_buffer_u16be(struct uwsgi_buffer *, uint16_t);
int uwsgi_buffer_u32be(struct uwsgi_buffer *, uint32_t);
int uwsgi_buffer_u32le(struct uwsgi_buffer *, uint32_t);
int uwsgi_buffer_u64le(struct uwsgi_buffer *, uint64_t);
int uwsgi_buffer_f32be(struct uwsgi_buffer *, float);
int uwsgi_buffer_u24be(struct uwsgi_buffer *, uint32_t);
int uwsgi_buffer_u64be(struct uwsgi_buffer *, uint64_t);
@@ -4423,116 +4388,6 @@ void uwsgi_opt_exit(char *, char *, void *);
int uwsgi_check_mountpoint(char *);
void uwsgi_master_check_mountpoints(void);
enum {
UWSGI_METRIC_COUNTER,
UWSGI_METRIC_GAUGE,
UWSGI_METRIC_ABSOLUTE,
UWSGI_METRIC_ALIAS,
};
struct uwsgi_metric_child;
struct uwsgi_metric_collector {
char *name;
int64_t (*func)(struct uwsgi_metric *);
struct uwsgi_metric_collector *next;
};
struct uwsgi_metric_threshold {
int64_t value;
uint8_t reset;
int64_t reset_value;
int32_t rate;
char *alarm;
char *msg;
size_t msg_len;
time_t last_alarm;
struct uwsgi_metric_threshold *next;
};
struct uwsgi_metric {
char *name;
char *oid;
size_t name_len;
size_t oid_len;
// pre-computed snmp representation
char *asn;
size_t asn_len;
// ABSOLUTE/COUNTER/GAUGE
uint8_t type;
// this could be taken from a file storage and must be always added to value by the collector (default 0)
int64_t initial_value;
// the value of the metric (point to a shared memory area)
int64_t *value;
// a custom blob you can attach to a metric
void *custom;
// the collection frequency
uint32_t freq;
time_t last_update;
// run this function to collect the value
struct uwsgi_metric_collector *collector;
// take the value from this pointer to a 64bit value
int64_t *ptr;
// get the initial value from this file, and store each update in it
char *filename;
// pointer to memory mapped storage
char *map;
// arguments for collectors
char *arg1;
char *arg2;
char *arg3;
int64_t arg1n;
int64_t arg2n;
int64_t arg3n;
struct uwsgi_metric_child *children;
struct uwsgi_metric_threshold *thresholds;
struct uwsgi_metric *next;
};
struct uwsgi_metric_child {
struct uwsgi_metric *um;
struct uwsgi_metric_child *next;
};
void uwsgi_setup_metrics(void);
void uwsgi_metrics_start_collector(void);
int uwsgi_metric_set(char *, char *, int64_t);
int uwsgi_metric_inc(char *, char *, int64_t);
int uwsgi_metric_dec(char *, char *, int64_t);
int uwsgi_metric_mul(char *, char *, int64_t);
int uwsgi_metric_div(char *, char *, int64_t);
int64_t uwsgi_metric_get(char *, char *);
int64_t uwsgi_metric_getn(char *, size_t, char *, size_t);
struct uwsgi_metric_collector *uwsgi_register_metric_collector(char *, int64_t (*)(struct uwsgi_metric *));
struct uwsgi_metric *uwsgi_register_metric(char *, char *, uint8_t, char *, void *, uint32_t, void *);
void uwsgi_metrics_collectors_setup(void);
struct uwsgi_metric *uwsgi_metric_find_by_name(char *);
struct uwsgi_metric *uwsgi_metric_find_by_namen(char *, size_t);
struct uwsgi_metric_child *uwsgi_metric_add_child(struct uwsgi_metric *, struct uwsgi_metric *);
struct uwsgi_metric *uwsgi_metric_find_by_oid(char *);
struct uwsgi_metric *uwsgi_metric_find_by_oidn(char *, size_t);
struct uwsgi_metric *uwsgi_metric_find_by_asn(char *, size_t);
int uwsgi_base128(struct uwsgi_buffer *, uint64_t, int);
struct wsgi_request *find_wsgi_req_proto_by_fd(int);
#ifdef __cplusplus
}
#endif
+1 -3
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '1.9.19'
uwsgi_version = '1.9.18.2'
import os
import re
@@ -538,7 +538,6 @@ class uConf(object):
'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/reader', 'core/writer', 'core/alarm', 'core/cron', 'core/hooks',
'core/plugins', 'core/lock', 'core/cache', 'core/daemons', 'core/errors', 'core/hash', 'core/master_events', 'core/chunked',
'core/queue', 'core/event', 'core/signal', 'core/strings', 'core/progress', 'core/timebomb', 'core/ini', 'core/fsmon', 'core/mount',
'core/metrics',
'core/rpc', 'core/gateway', 'core/loop', 'core/cookie', 'core/querystring', 'core/rb_timers', 'core/transformations', 'core/uwsgi']
# add protocols
self.gcc_list.append('proto/base')
@@ -546,7 +545,6 @@ class uConf(object):
self.gcc_list.append('proto/http')
self.gcc_list.append('proto/fastcgi')
self.gcc_list.append('proto/scgi')
self.gcc_list.append('proto/puwsgi')
self.include_path = []
if 'UWSGI_INCLUDES' in os.environ:
+1 -1
View File
@@ -19,7 +19,7 @@ postfork_chain = []
def get_free_signal():
for signum in range(0, 256):
for signum in xrange(0, 256):
if not uwsgi.signal_registered(signum):
return signum