From 136d443b5c38bee96f5d995dfea3629ef07564c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= <essen@ninenines.eu>
Date: Thu, 18 Jul 2019 09:59:28 +0200
Subject: Announce Ranch 2.0.0-rc.1

Adds Ranch 2.0 documentation and removes documentation for
very old Cowboy and Ranch, along with Erlang.mk documentation
which is available on its own website.
---
 .../ranch/2.0/guide/connection_draining.asciidoc   | 98 ++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 docs/en/ranch/2.0/guide/connection_draining.asciidoc

(limited to 'docs/en/ranch/2.0/guide/connection_draining.asciidoc')

diff --git a/docs/en/ranch/2.0/guide/connection_draining.asciidoc b/docs/en/ranch/2.0/guide/connection_draining.asciidoc
new file mode 100644
index 00000000..2ccdbc84
--- /dev/null
+++ b/docs/en/ranch/2.0/guide/connection_draining.asciidoc
@@ -0,0 +1,98 @@
+== Connection draining
+
+Stopping a Ranch listener via `ranch:stop_listener/1` will invariably kill
+all connection processes the listener hosts. However, you may want to stop
+a listener in a graceful fashion, ie by not accepting any new connections,
+but allowing the existing connection processes to exit by themselves instead
+of being killed.
+
+For this purpose, you should first suspend the listener you wish to
+stop gracefully, and then wait for its connection count to drop to
+zero.
+
+.Draining a single listener
+
+[source,erlang]
+----
+ok = ranch:suspend_listener(Ref),
+ok = ranch:wait_for_connections(Ref, '==', 0),
+ok = ranch:stop_listener(Ref).
+----
+
+If you want to drain more than just one listener, it may be important to first suspend
+them all before beginning to wait for their connection counts to reach zero. Otherwise,
+the not yet suspended listeners will still be accepting connections while you wait for
+the suspended ones to be drained.
+
+.Draining multiple listeners
+
+[source,erlang]
+----
+lists:foreach(
+	fun (Ref) ->
+		ok = ranch:suspend_listener(Ref)
+	end,
+	Refs
+),
+lists:foreach(
+	fun (Ref) ->
+		ok = ranch:wait_for_connections(Ref, '==', 0),
+		ok = ranch:stop_listener(Ref)
+	end,
+	Refs
+).
+----
+
+If you have long-running connection processes hosted by the listener you want to stop
+gracefully, draining may take a long time, possibly forever. If you just want to give
+the connection processes a chance to finish, but are not willing to wait for infinity,
+the waiting part could be handled in a separate process.
+
+.Draining a listener with a timeout
+
+[source,erlang]
+----
+ok = ranch:suspend_listener(Ref),
+{DrainPid, DrainRef} = spawn_monitor(
+	fun () ->
+		ok = ranch:wait_for_connections(Ref, '==', 0)
+	end
+),
+receive
+	{'DOWN', DrainRef, process, DrainPid, _} ->
+		ok
+after DrainTimeout ->
+	exit(DrainPid, kill),
+	ok
+end,
+ok = ranch:stop_listener(Ref).
+----
+
+To drain listeners automatically as part of your application shutdown routine,
+use the `prep_stop/1` function of your application module.
+
+.Draining listeners automatically on application shutdown
+
+[source,erlang]
+----
+-module(my_app).
+
+-behavior(application).
+
+-export([start/2]).
+-export([prep_stop/1]).
+-export([stop/1]).
+
+start(_StartType, _StartArgs) ->
+	{ok, _} = ranch:start_listener(my_listener, ranch_tcp, #{}, my_protocol, []),
+	my_app_sup:start_link().
+
+prep_stop(State) ->
+	ok = ranch:suspend_listener(my_listener),
+	ok = ranch:wait_for_connections(my_listener, '==', 0),
+	ok = ranch:stop_listener(my_listener),
+	State.
+
+stop(_State) ->
+	ok.
+----
-- 
cgit v1.2.3

