[MINOR] Allow shutdown of sessions when a server becomes unavailable
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.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index f35971f..f397f41 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -6667,6 +6667,15 @@
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
diff --git a/include/types/checks.h b/include/types/checks.h
index 75e32b6..a414630 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -74,6 +74,12 @@
};
enum {
+ HANA_ONMARKEDDOWN_NONE = 0,
+
+ HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS, /* Shutdown peer sessions */
+};
+
+enum {
HANA_OBS_NONE = 0,
HANA_OBS_LAYER4, /* Observe L4 - for example tcp */
diff --git a/include/types/server.h b/include/types/server.h
index cf0a0df..1a9d60d 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -125,6 +125,7 @@
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_* */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index cd05d83..7b46df0 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4251,6 +4251,18 @@
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 @@
}
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",
diff --git a/src/checks.c b/src/checks.c
index 82aceaa..6b34a37 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -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 @@
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 @@
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.