]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: checks: simplify failure notification using srv_set_stopped()
authorWilly Tarreau <w@1wt.eu>
Tue, 20 May 2014 20:32:27 +0000 (22:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 23 May 2014 12:29:11 +0000 (14:29 +0200)
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.

src/checks.c

index a92d5d77daac5caf9323d22cd08ce3409e1fee44..a30368f93defc7d5350a801ee64ffbcb05f8a7d3 100644 (file)
@@ -292,21 +292,12 @@ static void set_server_check_status(struct check *check, short status, const cha
        }
 }
 
-/* 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 @@ static void check_set_server_down(struct check *check)
        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 @@ void __health_adjust(struct server *s, short status)
                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 @@ static struct task *process_chk(struct task *t)
                /* 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 @@ static struct task *process_chk(struct task *t)
 
                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 */