From c974b4334e7ab660f9bf95653696c3663c02ead3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= <essen@ninenines.eu>
Date: Thu, 8 Aug 2019 16:33:09 +0200
Subject: Implement graceful shutdown

The graceful shutdown is implemented through a new 'closing'
state. This state is entered under different circumstances
depending on the protocol.

The gun:shutdown/1 function is now implemented and documented.
It allows shutting down the connection gracefully regardless
of the current state of the connection and for all protocols.
The behavior is entirely dependent on the protocol.

For HTTP/1.1 the connection stays up only until after the
current stream is complete; other streams are immediately
canceled.

For HTTP/2 a GOAWAY frame is sent and existing streams
continue to be processed. The connection is closed after
all streams are processed and the server's GOAWAY frame
is received.

For Websocket a close frame is sent. The connection is
closed when receiving the server's close frame.

In all cases the closing_timeout option defines how long
we wait, as a maximum, before closing the connection after
the graceful shutdown was started.

The graceful shutdown is also initiated when the owner
process goes away; when sending an HTTP/1.1 request
with the connection: close header; when receiving an
HTTP/1.1 response with the connection: close header;
when receiving an HTTP/1.0 response without a connection
header; when the server sends a GOAWAY HTTP/2 frame;
or when we send or receive a Websocket close frame.

Along with these changes, the gun:ws_send/2 function
now accepts a list of frames as argument. Those frames
may include a close frame that initiates the graceful
shutdown.
---
 doc/src/manual/gun.asciidoc | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

(limited to 'doc/src/manual/gun.asciidoc')

diff --git a/doc/src/manual/gun.asciidoc b/doc/src/manual/gun.asciidoc
index acc1454..b9fbbc2 100644
--- a/doc/src/manual/gun.asciidoc
+++ b/doc/src/manual/gun.asciidoc
@@ -16,7 +16,7 @@ Connection:
 
 * link:man:gun:open(3)[gun:open(3)] - Open a connection to the given host and port
 * link:man:gun:open_unix(3)[gun:open_unix(3)] - Open a connection to the given Unix domain socket
-// @todo * link:man:gun:shutdown(3)[gun:shutdown(3)] - Gracefully close the connection
+* link:man:gun:shutdown(3)[gun:shutdown(3)] - Gracefully close the connection
 * link:man:gun:close(3)[gun:close(3)] - Brutally close the connection
 * link:man:gun:info(3)[gun:info(3)] - Obtain information about the connection
 
@@ -144,6 +144,7 @@ Handshake timeout for tunneled TLS connections.
 [source,erlang]
 ----
 http_opts() :: #{
+    closing_timeout       => timeout(),
     flow                  => pos_integer(),
     keepalive             => timeout(),
     transform_header_name => fun((binary()) -> binary()),
@@ -157,6 +158,12 @@ The default value is given next to the option name:
 
 // @todo Document content_handlers and gun_sse_h.
 
+closing_timeout (15000)::
+
+Time to wait before brutally closing the connection when a
+graceful shutdown was requested via a call to
+link:man:gun:shutdown(3)[gun:shutdown(3)].
+
 flow - see below::
 
 The initial flow control value for all HTTP/1.1 streams.
@@ -188,8 +195,9 @@ HTTP version to use.
 [source,erlang]
 ----
 http2_opts() :: #{
-    flow      => pos_integer(),
-    keepalive => timeout()
+    closing_timeout => timeout(),
+    flow            => pos_integer(),
+    keepalive       => timeout()
 }
 ----
 
@@ -199,6 +207,12 @@ The default value is given next to the option name:
 
 // @todo Document content_handlers and gun_sse_h.
 
+closing_timeout (15000)::
+
+Time to wait before brutally closing the connection when a
+graceful shutdown was requested either via a call to
+link:man:gun:shutdown(3)[gun:shutdown(3)] or by the server.
+
 flow - see below::
 
 The initial flow control value for all HTTP/2 streams.
@@ -364,9 +378,10 @@ The pid of the process that will receive the response messages.
 [source,erlang]
 ----
 ws_opts() :: #{
-    compress  => boolean(),
-    flow      => pos_integer(),
-    protocols => [{binary(), module()}]
+    closing_timeout => timeout(),
+    compress        => boolean(),
+    flow            => pos_integer(),
+    protocols       => [{binary(), module()}]
 }
 ----
 
@@ -374,6 +389,12 @@ Configuration for the Websocket protocol.
 
 The default value is given next to the option name:
 
+closing_timeout (15000)::
+
+Time to wait before brutally closing the connection when a
+graceful shutdown was requested either via a call to
+link:man:gun:shutdown(3)[gun:shutdown(3)] or by the server.
+
 compress (false)::
 
 Whether to enable permessage-deflate compression. This does
-- 
cgit v1.2.3

