mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-06-16 02:15:48 +00:00
improved emperor on demand mode
This commit is contained in:
+17
-2
@@ -509,6 +509,10 @@ void emperor_del(struct uwsgi_instance *c_ui) {
|
||||
uwsgi.emperor_broodlord_count--;
|
||||
}
|
||||
|
||||
if (c_ui->socket_name) {
|
||||
free(c_ui->socket_name);
|
||||
}
|
||||
|
||||
free(c_ui);
|
||||
|
||||
}
|
||||
@@ -648,6 +652,9 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
|
||||
n_ui->first_run = uwsgi_now();
|
||||
n_ui->last_run = n_ui->first_run;
|
||||
n_ui->on_demand_fd = -1;
|
||||
if (socket_name) {
|
||||
n_ui->socket_name = uwsgi_str(socket_name);
|
||||
}
|
||||
|
||||
n_ui->pid = -1;
|
||||
|
||||
@@ -669,6 +676,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
|
||||
uwsgi_error("emperor_add()/bind()");
|
||||
free(n_ui);
|
||||
c_ui->ui_next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->on_demand_fd);
|
||||
@@ -1104,6 +1112,8 @@ void emperor_loop() {
|
||||
char notification_message[64];
|
||||
struct rlimit rl;
|
||||
|
||||
uwsgi.disable_nuclear_blast = 1;
|
||||
|
||||
uwsgi.emperor_stats_fd = -1;
|
||||
|
||||
if (uwsgi.emperor_pidfile) {
|
||||
@@ -1216,6 +1226,7 @@ void emperor_loop() {
|
||||
else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
|
||||
uwsgi_log("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
|
||||
char *zerg_name = uwsgi_concat3(ui_current->name, ":", "zerg");
|
||||
// here we discard socket name as broodlord/zerg cannot be on demand
|
||||
emperor_add(ui_current->scanner, zerg_name, uwsgi_now(), NULL, 0, ui_current->uid, ui_current->gid, NULL);
|
||||
free(zerg_name);
|
||||
}
|
||||
@@ -1312,7 +1323,7 @@ void emperor_loop() {
|
||||
}
|
||||
else {
|
||||
// UNSAFE
|
||||
emperor_add(ui_current->scanner, ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid, NULL);
|
||||
emperor_add(ui_current->scanner, ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid, ui_current->socket_name);
|
||||
emperor_del(ui_current);
|
||||
}
|
||||
break;
|
||||
@@ -1406,7 +1417,7 @@ void emperor_send_stats(int fd) {
|
||||
if (uwsgi_stats_keyval_comma(us, "id", c_ui->name))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) c_ui->pid))
|
||||
if (uwsgi_stats_keyslong_comma(us, "pid", (long long) c_ui->pid))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keylong_comma(us, "born", (unsigned long long) c_ui->born))
|
||||
goto end0;
|
||||
@@ -1425,6 +1436,9 @@ void emperor_send_stats(int fd) {
|
||||
if (uwsgi_stats_keylong_comma(us, "zerg", (unsigned long long) c_ui->zerg))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keyval_comma(us, "on_demand", c_ui->socket_name ? c_ui->socket_name : ""))
|
||||
goto end0;
|
||||
|
||||
if (uwsgi_stats_keylong_comma(us, "uid", (unsigned long long) c_ui->uid))
|
||||
goto end0;
|
||||
if (uwsgi_stats_keylong_comma(us, "gid", (unsigned long long) c_ui->gid))
|
||||
@@ -1543,6 +1557,7 @@ void uwsgi_emperor_start() {
|
||||
else {
|
||||
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
|
||||
}
|
||||
|
||||
if (uwsgi.emperor_pid < 0) {
|
||||
uwsgi_error("pid()");
|
||||
exit(1);
|
||||
|
||||
@@ -66,6 +66,7 @@ int bind_to_unix_dgram(char *socket_name) {
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlink(socket_name) != 0 && errno != ENOENT) {
|
||||
@@ -85,6 +86,7 @@ int bind_to_unix_dgram(char *socket_name) {
|
||||
#endif
|
||||
uwsgi_error("bind()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return serverfd;
|
||||
@@ -100,6 +102,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
if (strlen(socket_name) > 102) {
|
||||
uwsgi_log("invalid socket name\n");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (socket_name[0] == '@') {
|
||||
@@ -113,6 +116,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
if (uws_addr == NULL) {
|
||||
uwsgi_error("malloc()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(uws_addr, 0, sizeof(struct sockaddr_un));
|
||||
@@ -120,6 +124,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
if (abstract_socket == 0) {
|
||||
if (unlink(socket_name) != 0 && errno != ENOENT) {
|
||||
@@ -157,12 +162,14 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
#endif
|
||||
uwsgi_error("bind()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// chmod unix socket for lazy users
|
||||
@@ -578,11 +585,13 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
|
||||
uwsgi_error("SO_REUSEADDR setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -593,6 +602,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
if (setsockopt(serverfd, SOL_IP, IP_FREEBIND, (const void *) &uwsgi.freebind, sizeof(int)) < 0) {
|
||||
uwsgi_error("IP_FREEBIND setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -602,6 +612,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEPORT, (const void *) &uwsgi.reuse_port, sizeof(int)) < 0) {
|
||||
uwsgi_error("SO_REUSEPORT setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
uwsgi_log("!!! your system does not support SO_REUSEPORT !!!\n");
|
||||
@@ -628,6 +639,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_SNDTIMEO, (const void *) &tv, sizeof(struct timeval)) < 0) {
|
||||
uwsgi_error("SO_SNDTIMEO setsockopt()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,6 +674,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
}
|
||||
uwsgi_error("bind()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -669,12 +682,14 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
if (somaxconn > 0 && uwsgi.listen_queue > somaxconn) {
|
||||
uwsgi_log("Listen queue size is greater than the system max net.core.somaxconn (%li).\n", somaxconn);
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
uwsgi_nuclear_blast();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -315,6 +315,45 @@ int uwsgi_stats_keylong_comma(struct uwsgi_stats *us, char *key, unsigned long l
|
||||
return uwsgi_stats_comma(us);
|
||||
}
|
||||
|
||||
int uwsgi_stats_keyslong(struct uwsgi_stats *us, char *key, long long num) {
|
||||
|
||||
if (uwsgi_stats_apply_tabs(us))
|
||||
return -1;
|
||||
|
||||
char *ptr = us->base + us->pos;
|
||||
char *watermark = us->base + us->size;
|
||||
size_t available = watermark - ptr;
|
||||
|
||||
int ret = snprintf(ptr, available, "\"%s\":%lld", key, num);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
while (ret >= (int) available) {
|
||||
char *new_base = realloc(us->base, us->size + us->chunk);
|
||||
if (!new_base)
|
||||
return -1;
|
||||
us->base = new_base;
|
||||
us->size += us->chunk;
|
||||
ptr = us->base + us->pos;
|
||||
watermark = us->base + us->size;
|
||||
available = watermark - ptr;
|
||||
ret = snprintf(ptr, available, "\"%s\":%lld", key, num);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
us->pos += ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_stats_keyslong_comma(struct uwsgi_stats *us, char *key, long long num) {
|
||||
int ret = uwsgi_stats_keyslong(us, key, num);
|
||||
if (ret)
|
||||
return -1;
|
||||
return uwsgi_stats_comma(us);
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_send_stats(int fd, struct uwsgi_stats *(*func) (void)) {
|
||||
|
||||
struct sockaddr_un client_src;
|
||||
|
||||
@@ -1041,6 +1041,9 @@ void grace_them_all(int signum) {
|
||||
|
||||
void uwsgi_nuclear_blast() {
|
||||
|
||||
// the Emperor (as an example) cannot nuke itself
|
||||
if (uwsgi.disable_nuclear_blast) return;
|
||||
|
||||
if (!uwsgi.workers) {
|
||||
reap_them_all(0);
|
||||
}
|
||||
|
||||
@@ -1626,6 +1626,8 @@ struct uwsgi_server {
|
||||
// run a shell script passing the vassal as the only argument, the stdout is used as the socket
|
||||
char *emperor_on_demand_exec;
|
||||
|
||||
int disable_nuclear_blast;
|
||||
|
||||
time_t next_heartbeat;
|
||||
int heartbeat;
|
||||
struct uwsgi_string_list *emperor;
|
||||
@@ -3404,6 +3406,8 @@ int uwsgi_stats_keyvaln_comma(struct uwsgi_stats *, char *, char *, int);
|
||||
int uwsgi_stats_key(struct uwsgi_stats *, char *);
|
||||
int uwsgi_stats_keylong(struct uwsgi_stats *, char *, unsigned long long);
|
||||
int uwsgi_stats_keylong_comma(struct uwsgi_stats *, char *, unsigned long long);
|
||||
int uwsgi_stats_keyslong(struct uwsgi_stats *, char *, long long);
|
||||
int uwsgi_stats_keyslong_comma(struct uwsgi_stats *, char *, long long);
|
||||
int uwsgi_stats_str(struct uwsgi_stats *, char *);
|
||||
|
||||
char *uwsgi_substitute(char *, char *, char *);
|
||||
@@ -3517,6 +3521,7 @@ struct uwsgi_instance {
|
||||
gid_t gid;
|
||||
|
||||
int on_demand_fd;
|
||||
char *socket_name;
|
||||
};
|
||||
|
||||
struct uwsgi_instance *emperor_get_by_fd(int);
|
||||
|
||||
Reference in New Issue
Block a user