void ngx_http_healthcheck_mark_finished(ngx_http_healthcheck_status_t *stat) { #ifdef NGX_SUPERVISORD_MODULE ngx_http_upstream_rr_peers_t *peers = stat->conf->peer.data; #endif ngx_log_debug2(NGX_LOG_DEBUG_HTTP, stat->health_ev.log, 0, "healthcheck: Finished %V, state %d", &stat->peer->name, stat->state); if (stat->state == NGX_HEALTH_OK) { if (stat->shm->last_down) { stat->shm->last_down = 0; stat->shm->concurrent = 1; stat->shm->since = ngx_current_msec; #ifdef NGX_SUPERVISORD_MODULE (void) ngx_supervisord_execute(stat->conf, NGX_SUPERVISORD_CMD_START, peers->peer[stat->index].onumber, NULL); #endif } else { stat->shm->concurrent++; } } else { if (stat->shm->last_down) { stat->shm->concurrent++; } else { stat->shm->last_down = 1; stat->shm->concurrent = 1; stat->shm->since = ngx_current_msec; #ifdef NGX_SUPERVISORD_MODULE (void) ngx_supervisord_execute(stat->conf, NGX_SUPERVISORD_CMD_STOP, peers->peer[stat->index].onumber, NULL); #endif } } if (stat->shm->concurrent >= stat->conf->health_failcount) { if (stat->shm->down != stat->shm->last_down) { stat->shm->down = stat->shm->last_down; ngx_log_error(NGX_LOG_NOTICE, stat->health_ev.log, 0, "healthcheck peer: %V, down status changed to %A", &stat->peer->name, stat->shm->down); } } stat->shm->down_code = stat->state; ngx_close_connection(stat->pc->connection); stat->pc->connection = NULL; stat->state = NGX_HEALTH_WAITING; if (!ngx_terminate && !ngx_exiting && !ngx_quit) { ngx_add_timer(&stat->health_ev, stat->conf->health_delay); } else { ngx_http_healthcheck_clear_events(stat->health_ev.log); } stat->shm->action_time = ngx_current_msec; }
static void ngx_http_healthcheck_try_for_ownership(ngx_event_t *event) { ngx_http_healthcheck_status_t * stat; ngx_int_t i_own_it; stat = event->data; if (ngx_terminate || ngx_exiting || ngx_quit) { ngx_http_healthcheck_clear_events(stat->health_ev.log); return; } i_own_it = 0; // nxg_time_update(0, 0); // Spinlock. So don't own for a long time! // Use spinlock so two worker processes don't try to healthcheck the same // peer ngx_spinlock(&stat->shm->lock, ngx_pid, 1024); if (stat->shm->owner == ngx_pid) { i_own_it = 1; } else if (ngx_current_msec - stat->shm->action_time >= (stat->conf->health_delay + stat->conf->health_timeout) * 3) { stat->shm->owner = ngx_pid; stat->shm->action_time = ngx_current_msec; stat->state = NGX_HEALTH_WAITING; ngx_http_healthcheck_begin_healthcheck(&stat->health_ev); i_own_it = 1; } if (!ngx_atomic_cmp_set(&stat->shm->lock, ngx_pid, 0)) { ngx_log_error(NGX_LOG_CRIT, event->log, 0, "healthcheck: spinlock didn't work. Should be %P, but isn't", ngx_pid); stat->shm->lock = 0; } if (!i_own_it) { // Try again for ownership later in case the guy that DOES own it dies or // something ngx_add_timer(&stat->ownership_ev, 5000); } }