diff --git a/core/emperor.c b/core/emperor.c index 2a64a00d..51769e87 100644 --- a/core/emperor.c +++ b/core/emperor.c @@ -59,12 +59,12 @@ void uwsgi_emperor_blacklist_add(char *id) { uebi->throttle_level += (uwsgi.emperor_throttle * 1000); } else { - uwsgi_log("[emperor] maximum throttle level for vassal %s reached !!!\n", id); + uwsgi_log_verbose("[emperor] maximum throttle level for vassal %s reached !!!\n", id); uebi->throttle_level = uebi->throttle_level / 2; } uebi->attempt++; if (uebi->attempt == 2) { - uwsgi_log("[emperor] unloyal bad behaving vassal found: %s throttling it...\n", id); + uwsgi_log_verbose("[emperor] unloyal bad behaving vassal found: %s throttling it...\n", id); } return; } @@ -603,7 +603,7 @@ void emperor_del(struct uwsgi_instance *c_ui) { uwsgi_log("[emperor] %s stop-hook returned %d\n", c_ui->name, stop_hook_ret); } - uwsgi_log("[emperor] removed uwsgi instance %s\n", c_ui->name); + uwsgi_log_verbose("[emperor] removed uwsgi instance %s\n", c_ui->name); // put the instance in the blacklist (or update its throttling value) if (!c_ui->loyal) { uwsgi_emperor_blacklist_add(c_ui->name); @@ -632,7 +632,7 @@ void emperor_stop(struct uwsgi_instance *c_ui) { c_ui->status = 1; c_ui->cursed_at = uwsgi_now(); - uwsgi_log("[emperor] stop the uwsgi instance %s\n", c_ui->name); + uwsgi_log_verbose("[emperor] stop the uwsgi instance %s\n", c_ui->name); } void emperor_curse(struct uwsgi_instance *c_ui) { @@ -642,7 +642,7 @@ void emperor_curse(struct uwsgi_instance *c_ui) { c_ui->status = 1; c_ui->cursed_at = uwsgi_now(); - uwsgi_log("[emperor] curse the uwsgi instance %s (pid: %d)\n", c_ui->name, (int) c_ui->pid); + uwsgi_log_verbose("[emperor] curse the uwsgi instance %s (pid: %d)\n", c_ui->name, (int) c_ui->pid); } @@ -675,8 +675,12 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) { c_ui->respawns++; c_ui->last_mod = mod; c_ui->last_run = uwsgi_now(); + // reset readyness + c_ui->ready = 0; + // reset accepting + c_ui->accepting = 0; - uwsgi_log("[emperor] reload the uwsgi instance %s\n", c_ui->name); + uwsgi_log_verbose("[emperor] reload the uwsgi instance %s\n", c_ui->name); } void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid, char *socket_name) { @@ -763,6 +767,9 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha n_ui->uid = uid; n_ui->gid = gid; n_ui->last_mod = born; + // start non-ready + n_ui->last_ready = 0; + n_ui->ready = 0; // start without loyalty n_ui->last_loyal = 0; n_ui->loyal = 0; @@ -1552,7 +1559,7 @@ void emperor_loop() { if (byte == 17) { ui_current->loyal = 1; ui_current->last_loyal = uwsgi_now(); - uwsgi_log("[emperor] vassal %s is now loyal\n", ui_current->name); + uwsgi_log_verbose("[emperor] vassal %s is now loyal\n", ui_current->name); // remove it from the blacklist uwsgi_emperor_blacklist_remove(ui_current->name); // TODO post-start hook @@ -1565,12 +1572,22 @@ void emperor_loop() { emperor_stop(ui_current); } 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); + uwsgi_log_verbose("[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); } + else if (byte == 5) { + ui_current->accepting = 1; + ui_current->last_accepting = uwsgi_now(); + uwsgi_log_verbose("[emperor] vassal %s is ready to accept requests\n", ui_current->name); + } + else if (byte == 1) { + ui_current->ready = 1; + ui_current->last_ready = uwsgi_now(); + uwsgi_log_verbose("[emperor] vassal %s has been spawned\n", ui_current->name); + } } } else { @@ -1773,8 +1790,16 @@ void emperor_send_stats(int fd) { goto end0; if (uwsgi_stats_keylong_comma(us, "loyal", (unsigned long long) c_ui->loyal)) goto end0; + if (uwsgi_stats_keylong_comma(us, "ready", (unsigned long long) c_ui->ready)) + goto end0; + if (uwsgi_stats_keylong_comma(us, "accepting", (unsigned long long) c_ui->accepting)) + goto end0; if (uwsgi_stats_keylong_comma(us, "last_loyal", (unsigned long long) c_ui->last_loyal)) goto end0; + if (uwsgi_stats_keylong_comma(us, "last_ready", (unsigned long long) c_ui->last_ready)) + goto end0; + if (uwsgi_stats_keylong_comma(us, "last_accepting", (unsigned long long) c_ui->last_accepting)) + goto end0; if (uwsgi_stats_keylong_comma(us, "first_run", (unsigned long long) c_ui->first_run)) goto end0; if (uwsgi_stats_keylong_comma(us, "last_run", (unsigned long long) c_ui->last_run)) @@ -2105,3 +2130,16 @@ void uwsgi_master_manage_emperor_proxy() { close(ep_client); } + +static void emperor_notify_ready() { + if (!uwsgi.has_emperor) return; + char byte = 1; + if (write(uwsgi.emperor_fd, &byte, 1) != 1) { + uwsgi_error("emperor_notify_ready()/write()"); + } +} + +void uwsgi_setup_emperor() { + if (!uwsgi.has_emperor) return; + uwsgi.notify_ready = emperor_notify_ready; +} diff --git a/core/master_checks.c b/core/master_checks.c index 2774ebfb..6b58522e 100644 --- a/core/master_checks.c +++ b/core/master_checks.c @@ -49,7 +49,7 @@ void uwsgi_master_check_chain() { uwsgi_block_signal(SIGHUP); for(i=1;i<=uwsgi.numproc;i++) { // do not curse a worker until the old one is ready - if (uwsgi.workers[i].ready == 0) break; + if (uwsgi.workers[i].accepting == 0) break; if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].cursed_at == 0 && i == uwsgi.status.chain_reloading) { uwsgi_curse(i, SIGHUP); break; diff --git a/core/master_utils.c b/core/master_utils.c index 894ed252..3125bc27 100644 --- a/core/master_utils.c +++ b/core/master_utils.c @@ -592,8 +592,8 @@ void uwsgi_fixup_fds(int wid, int muleid, struct uwsgi_gateway *ug) { int uwsgi_respawn_worker(int wid) { int respawns = uwsgi.workers[wid].respawn_count; - // the workers is not ready (obviously) - uwsgi.workers[wid].ready = 0; + // the workers is not accepting (obviously) + uwsgi.workers[wid].accepting = 0; // we count the respawns before errors... uwsgi.workers[wid].respawn_count++; // ... same for update time @@ -992,7 +992,7 @@ struct uwsgi_stats *uwsgi_master_generate_stats() { goto end; if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) uwsgi.workers[i + 1].pid)) goto end; - if (uwsgi_stats_keylong_comma(us, "ready", (unsigned long long) uwsgi.workers[i + 1].ready)) + if (uwsgi_stats_keylong_comma(us, "accepting", (unsigned long long) uwsgi.workers[i + 1].accepting)) goto end; if (uwsgi_stats_keylong_comma(us, "requests", (unsigned long long) uwsgi.workers[i + 1].requests)) goto end; diff --git a/core/notify.c b/core/notify.c index 4a550aa4..4e47e735 100644 --- a/core/notify.c +++ b/core/notify.c @@ -1,4 +1,4 @@ -#include "uwsgi.h" +#include extern struct uwsgi_server uwsgi; diff --git a/core/utils.c b/core/utils.c index 78233585..38e918af 100644 --- a/core/utils.c +++ b/core/utils.c @@ -1162,7 +1162,7 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { } - // ready to accept request, if i am a vassal signal Emperor about my loyalty + // after the first request, if i am a vassal, signal Emperor about my loyalty if (uwsgi.has_emperor && !uwsgi.loyal) { uwsgi_log("announcing my loyalty to the Emperor...\n"); char byte = 17; diff --git a/core/uwsgi.c b/core/uwsgi.c index 582250d1..ce7f3f27 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -2601,6 +2601,7 @@ int uwsgi_start(void *v_argv) { uwsgi_setup_systemd(); uwsgi_setup_upstart(); uwsgi_setup_zerg(); + uwsgi_setup_emperor(); } @@ -3249,8 +3250,15 @@ void uwsgi_ignition() { } } - // mark the worker as "ready" (this is a mark used by chain reloading) - uwsgi.workers[uwsgi.mywid].ready = 1; + // mark the worker as "accepting" (this is a mark used by chain reloading) + uwsgi.workers[uwsgi.mywid].accepting = 1; + // ready to accept request, if i am a vassal signal Emperor about it + if (uwsgi.has_emperor && uwsgi.mywid == 1) { + char byte = 5; + if (write(uwsgi.emperor_fd, &byte, 1) != 1) { + uwsgi_error("write()"); + } + } if (uwsgi.loop) { void (*u_loop) (void) = uwsgi_get_loop(uwsgi.loop); diff --git a/uwsgi.h b/uwsgi.h index 77d75418..eb4da133 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2786,7 +2786,7 @@ struct uwsgi_worker { struct uwsgi_core *cores; - int ready; + int accepting; char name[0xff]; }; @@ -3776,6 +3776,7 @@ void uwsgi_setup_systemd(); void uwsgi_setup_upstart(); void uwsgi_setup_zerg(); void uwsgi_setup_inherited_sockets(); +void uwsgi_setup_emperor(); #ifdef UWSGI_SSL void uwsgi_ssl_init(void); @@ -3846,6 +3847,8 @@ struct uwsgi_instance { time_t born; time_t last_mod; time_t last_loyal; + time_t last_accepting; + time_t last_ready; time_t last_run; time_t first_run; @@ -3865,6 +3868,9 @@ struct uwsgi_instance { int zerg; + int ready; + int accepting; + struct uwsgi_emperor_scanner *scanner; uid_t uid;