]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] Allow shutdown of sessions when a server becomes unavailable
authorSimon Horman <horms@verge.net.au>
Tue, 21 Jun 2011 05:34:58 +0000 (14:34 +0900)
committerWilly Tarreau <w@1wt.eu>
Tue, 21 Jun 2011 20:00:21 +0000 (22:00 +0200)
This adds the "on-marked-down shutdown-sessions" statement on "server" lines,
which causes all sessions established on a server to be killed at once when
the server goes down. The task's priority is reniced to the highest value
(1024) so that servers holding many tasks don't cause a massive slowdown due
to the wakeup storm.

doc/configuration.txt
include/types/checks.h
include/types/server.h
src/cfgparse.c
src/checks.c

index f35971fa7c11525c9eb6448347627b97d2c52046..f397f411c6d872a06a22cde8bc7b35f7f72935a0 100644 (file)
@@ -6667,6 +6667,15 @@ on-error <mode>
 
   See also the "check", "observe" and "error-limit".
 
+on-marked-down <action>
+  Modify what occurs when a server is marked down.
+  Currently one action is available:
+  - shutdown-sessions: Shutdown peer sessions
+
+  Actions are disabled by default
+
+  Supported in default-server: Yes
+
 port <port>
   Using the "port" parameter, it becomes possible to use a different port to
   send health-checks. On some servers, it may be desirable to dedicate a port
index 75e32b6b4b31163b9cb8349d6579ba3a618bc699..a41463062fec9c08e94c0302a18ea6a5f44f6d21 100644 (file)
@@ -73,6 +73,12 @@ enum {
        HANA_ONERR_MARKDWN,             /* Mark this server down, now! */
 };
 
+enum {
+       HANA_ONMARKEDDOWN_NONE  = 0,
+
+       HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS,     /* Shutdown peer sessions */
+};
+
 enum {
        HANA_OBS_NONE           = 0,
 
index cf0a0df06a3e9d4ad8934fe6791b2e696a32733d..1a9d60d327d8c3e4908359f5ff1fc3a2d6a537cd 100644 (file)
@@ -125,6 +125,7 @@ struct server {
        int rise, fall;                         /* time in iterations */
        int consecutive_errors_limit;           /* number of consecutive errors that triggers an event */
        short observe, onerror;                 /* observing mode: one of HANA_OBS_*; what to do on error: on of ANA_ONERR_* */
+       short onmarkeddown;                     /* what to do when marked down: on of HANA_ONMARKEDDOWN_* */
        int inter, fastinter, downinter;        /* checks: time in milliseconds */
        int slowstart;                          /* slowstart time in seconds (ms in the conf) */
        int result;                             /* health-check result : SRV_CHK_* */
index cd05d83807c6dfd0d7841a21ae2fc90cdc230cc7..7b46df0bf26e186d4ce926607973cf7fca380c4b 100644 (file)
@@ -4251,6 +4251,18 @@ stats_error_parsing:
 
                                cur_arg += 2;
                        }
+                       else if (!strcmp(args[cur_arg], "on-marked-down")) {
+                               if (!strcmp(args[cur_arg + 1], "shutdown-sessions"))
+                                       newsrv->onmarkeddown = HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS;
+                               else {
+                                       Alert("parsing [%s:%d]: '%s' expects 'shutdown-sessions' but got '%s'\n",
+                                               file, linenum, args[cur_arg], args[cur_arg + 1]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               cur_arg += 2;
+                       }
                        else if (!strcmp(args[cur_arg], "error-limit")) {
                                if (!*args[cur_arg + 1]) {
                                        Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
@@ -4430,7 +4442,7 @@ stats_error_parsing:
                        }
                        else {
                                if (!defsrv)
-                                       Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'observer', 'on-error', 'error-limit', 'check', 'disabled', 'track', 'id', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'send-proxy', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
+                                       Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'observer', 'on-error', 'on-marked-down', 'error-limit', 'check', 'disabled', 'track', 'id', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'send-proxy', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
                                              file, linenum, newsrv->id);
                                else
                                        Alert("parsing [%s:%d]: default-server only supports options 'on-error', 'error-limit', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'port', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
index 82aceaaa2ba2b7cfcecafe1b44d92776177d13b6..6b34a377bee79b5c67f23259af9d4bc5074fd82c 100644 (file)
@@ -45,6 +45,7 @@
 #include <proto/proto_tcp.h>
 #include <proto/proxy.h>
 #include <proto/server.h>
+#include <proto/session.h>
 #include <proto/stream_interface.h>
 #include <proto/task.h>
 
@@ -357,6 +358,24 @@ static int check_for_pending(struct server *s)
        return xferred;
 }
 
+/* Shutdown connections when their server goes down.
+ */
+static void shutdown_sessions(struct server *srv)
+{
+       struct session *session, *session_bck;
+
+       list_for_each_entry_safe(session, session_bck,
+                                &srv->actconns, by_srv) {
+               if (session->srv_conn == srv &&
+                   !(session->req->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
+                               buffer_shutw_now(session->req);
+                               buffer_shutr_now(session->rep);
+                               session->task->nice = 1024;
+                               task_wakeup(session->task, TASK_WOKEN_OTHER);
+               }
+       }
+}
+
 /* Sets server <s> 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
@@ -380,6 +399,9 @@ void set_server_down(struct server *s)
                s->state &= ~(SRV_RUNNING | SRV_GOINGDOWN);
                s->proxy->lbprm.set_server_status_down(s);
 
+               if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
+                       shutdown_sessions(s);
+
                /* 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.