]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: h2: prepare a graceful shutdown when the frontend is stopped
authorWilly Tarreau <w@1wt.eu>
Sat, 30 Dec 2017 17:08:13 +0000 (18:08 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 30 Dec 2017 17:08:13 +0000 (18:08 +0100)
During a reload operation, instead of keeping the H2 connections opened
forever causing confusion during configuration changes, let's send a
graceful shutdown so that the client knows that it would better open a
new connection for future requests. We can't really catch the signal
from H2, but we can advertise this graceful shutdown upon the next I/O
event (eg: a WINDOW_UPDATE from the client or a new request). One of
the visible effect is that the old process quits much faster.

This patch should be backported to 1.8 since it is affected by this
problem.

src/mux_h2.c

index 71660f8e8a0dd4dc94d2d9db30f37f9f6912a18d..c6e15eca8522051255b8a3a7dd61ebcc408805a4 100644 (file)
@@ -2250,6 +2250,7 @@ static void h2_send(struct connection *conn)
 static int h2_wake(struct connection *conn)
 {
        struct h2c *h2c = conn->mux_ctx;
+       struct session *sess = conn->owner;
 
        if (h2c->dbuf->i && !(h2c->flags & H2_CF_DEM_BLOCK_ANY)) {
                h2_process_demux(h2c);
@@ -2261,6 +2262,18 @@ static int h2_wake(struct connection *conn)
                        h2c->flags &= ~H2_CF_DEM_DFULL;
        }
 
+       if (sess && unlikely(sess->fe->state == PR_STSTOPPED)) {
+               /* frontend is stopping, reload likely in progress, let's try
+                * to announce a graceful shutdown if not yet done. We don't
+                * care if it fails, it will be tried again later.
+                */
+               if (!(h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED))) {
+                       if (h2c->last_sid < 0)
+                               h2c->last_sid = (1U << 31) - 1;
+                       h2c_send_goaway_error(h2c, NULL);
+               }
+       }
+
        /*
         * If we received early data, try to wake any stream, just in case
         * at least one of them was waiting for the handshake