diff options
author | Loïc Hoguin <[email protected]> | 2015-12-18 15:46:39 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2015-12-18 15:46:39 +0100 |
commit | cfb5386fafaa8ba75bb4720403e90b2581643f9f (patch) | |
tree | 05ddc7a7ec6960a281d11504c69d215bdbd8d931 | |
parent | 666e5398cee49cad985bfe522e9b9b9bf0032417 (diff) | |
download | ranch-cfb5386fafaa8ba75bb4720403e90b2581643f9f.tar.gz ranch-cfb5386fafaa8ba75bb4720403e90b2581643f9f.tar.bz2 ranch-cfb5386fafaa8ba75bb4720403e90b2581643f9f.zip |
Fix node shutdown getting stuck
When SSL is stopped before Ranch, the acceptors crash and
Ranch tries to restart them. The problem is that the
ranch_ssl:listen/1 call was trying to start the SSL
application to make sure it works (an old artifact from
when releases were not ubiquitous). Because the application
controller is trying to shutdown Ranch, and Ranch tries to
tell it to start an application, everything would get stuck.
To avoid a breaking change, we move this in the start_listener
call (or child_spec). Note that there are still logs when the
SSL application is closed, because the acceptors crash. But
at least we don't block node shutdown anymore.
In Ranch 2.0, we will implement the proper fix which is to
simply depend on the SSL application normally. Nowadays, it's
not too difficult to build a release that excludes applications
we don't want, although we should document that in the Ranch
user guide.
-rw-r--r-- | src/ranch.erl | 10 | ||||
-rw-r--r-- | src/ranch_ssl.erl | 1 |
2 files changed, 10 insertions, 1 deletions
diff --git a/src/ranch.erl b/src/ranch.erl index d2cd74b..32a0be6 100644 --- a/src/ranch.erl +++ b/src/ranch.erl @@ -48,6 +48,8 @@ start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) when is_integer(NbAcceptors) andalso is_atom(Transport) andalso is_atom(Protocol) -> _ = code:ensure_loaded(Transport), + %% @todo Remove in Ranch 2.0 and simply require ssl. + _ = ensure_ssl(Transport), case erlang:function_exported(Transport, name, 0) of false -> {error, badarg}; @@ -90,10 +92,18 @@ stop_listener(Ref) -> child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) when is_integer(NbAcceptors) andalso is_atom(Transport) andalso is_atom(Protocol) -> + %% @todo Remove in Ranch 2.0 and simply require ssl. + _ = ensure_ssl(Transport), {{ranch_listener_sup, Ref}, {ranch_listener_sup, start_link, [ Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts ]}, permanent, infinity, supervisor, [ranch_listener_sup]}. +%% @todo Remove in Ranch 2.0 and simply require ssl. +ensure_ssl(ranch_ssl) -> + require([crypto, asn1, public_key, ssl]); +ensure_ssl(_) -> + ok. + -spec accept_ack(ref()) -> ok. accept_ack(Ref) -> receive {shoot, Ref, Transport, Socket, AckTimeout} -> diff --git a/src/ranch_ssl.erl b/src/ranch_ssl.erl index 5e8e68a..e9bbff2 100644 --- a/src/ranch_ssl.erl +++ b/src/ranch_ssl.erl @@ -85,7 +85,6 @@ messages() -> {ssl, ssl_closed, ssl_error}. -spec listen(opts()) -> {ok, ssl:sslsocket()} | {error, atom()}. listen(Opts) -> - ranch:require([crypto, asn1, public_key, ssl]), true = lists:keymember(cert, 1, Opts) orelse lists:keymember(certfile, 1, Opts), Opts2 = ranch:set_option_default(Opts, backlog, 1024), |