Browse Source

Document connection draining

juhlig 6 years ago
parent
commit
c7485760d3
2 changed files with 71 additions and 0 deletions
  1. 2 0
      doc/src/guide/book.asciidoc
  2. 69 0
      doc/src/guide/connection_draining.asciidoc

+ 2 - 0
doc/src/guide/book.asciidoc

@@ -21,6 +21,8 @@ include::parsers.asciidoc[Writing parsers]
 
 include::ssl_auth.asciidoc[SSL client authentication]
 
+include::connection_draining.asciidoc[Connection draining]
+
 = Advanced
 
 include::internals.asciidoc[Internals]

+ 69 - 0
doc/src/guide/connection_draining.asciidoc

@@ -0,0 +1,69 @@
+== 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 listeners 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).
+----