MEDIUM: checks: simplify failure notification using srv_set_stopped()
Function check_set_server_down() used to set a server down. Now it first
checks if the health check's result differs from the server's state, and
only calls srv_set_stopped() if the check reports a failure while the
server is not down. Thanks to this, the conditions that were present
around its call could be removed. The function was also renamed
check_notify_failure() to better report this change.
diff --git a/src/checks.c b/src/checks.c
index a92d5d7..a30368f 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -292,21 +292,12 @@
}
}
-/* Marks the check <check>'s server down, notifies by all available means,
- * recounts the remaining servers on the proxy and transfers queued sessions
- * whenever possible to other servers. It automatically recomputes the number
- * of servers, but not the map. Maintenance servers are ignored.
+/* Marks the check <check>'s server down if the current check is already failed
+ * and the server is not down yet nor in maintenance.
*/
-static void check_set_server_down(struct check *check)
+static void check_notify_failure(struct check *check)
{
struct server *s = check->server;
- struct server *srv;
- int prev_srv_count = s->proxy->srv_bck + s->proxy->srv_act;
- int srv_was_stopping = (s->state == SRV_ST_STOPPING);
- int xferred;
-
- if ((s->admin & SRV_ADMF_MAINT) || s->state == SRV_ST_STOPPED)
- return;
/* The agent secondary check should only cause a server to be marked
* as down if check->status is HCHK_STATUS_L7STS, which indicates
@@ -317,44 +308,11 @@
if ((check->state & CHK_ST_AGENT) && check->status != HCHK_STATUS_L7STS)
return;
- check->health = 0; /* failure */
- s->last_change = now.tv_sec;
- s->state = SRV_ST_STOPPED;
- if (s->proxy->lbprm.set_server_status_down)
- s->proxy->lbprm.set_server_status_down(s);
-
- if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
- srv_shutdown_sessions(s, SN_ERR_DOWN);
-
- /* we might have sessions queued on this server and waiting for
- * a connection. Those which are redispatchable will be queued
- * to another server or to the proxy itself.
- */
- xferred = pendconn_redistribute(s);
-
- chunk_printf(&trash,
- "%sServer %s/%s is DOWN", s->flags & SRV_F_BACKUP ? "Backup " : "",
- s->proxy->id, s->id);
-
- srv_append_status(&trash, s,
- ((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? check_reason_string(check) : NULL),
- xferred, 0);
-
- Warning("%s.\n", trash.str);
-
- /* we don't send an alert if the server was previously paused */
- if (srv_was_stopping)
- send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
- else
- send_log(s->proxy, LOG_ALERT, "%s.\n", trash.str);
-
- if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
- set_backend_down(s->proxy);
-
- s->counters.down_trans++;
+ if (check->health > 0)
+ return;
- for (srv = s->trackers; srv; srv = srv->tracknext)
- check_set_server_down(&srv->check);
+ /* We only report a reason for the check if we did not do so previously */
+ srv_set_stopped(s, (!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? check_reason_string(check) : NULL);
}
/* Marks the check <check> as valid and tries to set its server up, provided
@@ -542,18 +500,14 @@
case HANA_ONERR_FAILCHK:
/* simulate a failed health check */
set_server_check_status(&s->check, HCHK_STATUS_HANA, trash.str);
- if (!s->check.health)
- check_set_server_down(&s->check);
-
+ check_notify_failure(&s->check);
break;
case HANA_ONERR_MARKDWN:
/* mark server down */
s->check.health = s->check.rise;
set_server_check_status(&s->check, HCHK_STATUS_HANA, trash.str);
- if (!s->check.health)
- check_set_server_down(&s->check);
-
+ check_notify_failure(&s->check);
break;
default:
@@ -1495,8 +1449,7 @@
/* here, we have seen a synchronous error, no fd was allocated */
check->state &= ~CHK_ST_INPROGRESS;
- if (!check->health)
- check_set_server_down(check);
+ check_notify_failure(check);
/* we allow up to min(inter, timeout.connect) for a connection
* to establish but only when timeout.check is set
@@ -1545,8 +1498,7 @@
if (check->result == CHK_RES_FAILED) {
/* a failure or timeout detected */
- if (!check->health && check->server->state != SRV_ST_STOPPED)
- check_set_server_down(check);
+ check_notify_failure(check);
}
else if (check->result == CHK_RES_CONDPASS && s->state != SRV_ST_STOPPED && !(s->admin & SRV_ADMF_MAINT)) {
/* check is OK but asks for drain mode */