diff options
author | juhlig <[email protected]> | 2019-07-05 15:42:22 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2019-07-10 16:42:35 +0200 |
commit | c7485760d3868219ea2406f225c0c21d6b753ec0 (patch) | |
tree | 9257634daf8c705d8328a0bcb69279df5f1db7b4 /doc/src/guide | |
parent | 1c2a8ae750c73f4768c846f85235893cd1e380ea (diff) | |
download | ranch-c7485760d3868219ea2406f225c0c21d6b753ec0.tar.gz ranch-c7485760d3868219ea2406f225c0c21d6b753ec0.tar.bz2 ranch-c7485760d3868219ea2406f225c0c21d6b753ec0.zip |
Document connection draining
Diffstat (limited to 'doc/src/guide')
-rw-r--r-- | doc/src/guide/book.asciidoc | 2 | ||||
-rw-r--r-- | doc/src/guide/connection_draining.asciidoc | 69 |
2 files changed, 71 insertions, 0 deletions
diff --git a/doc/src/guide/book.asciidoc b/doc/src/guide/book.asciidoc index d4080b3..e87e7b3 100644 --- a/doc/src/guide/book.asciidoc +++ b/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] diff --git a/doc/src/guide/connection_draining.asciidoc b/doc/src/guide/connection_draining.asciidoc new file mode 100644 index 0000000..cee4dfa --- /dev/null +++ b/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). +---- |