aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2015-08-20 16:05:50 +0200
committerLoïc Hoguin <[email protected]>2015-08-20 16:05:50 +0200
commitee1f82782835096208059ea14d52bf2cc0283323 (patch)
tree66d0dd5f157b088027a74c546a7f480bd974ae29
parentc867ec582d445b251ff659ba23f522b5278d5119 (diff)
downloadranch-ee1f82782835096208059ea14d52bf2cc0283323.tar.gz
ranch-ee1f82782835096208059ea14d52bf2cc0283323.tar.bz2
ranch-ee1f82782835096208059ea14d52bf2cc0283323.zip
Ensure ranch_conns_sup doesn't crash on protocol start crash
-rw-r--r--src/ranch_conns_sup.erl9
-rw-r--r--test/acceptor_SUITE.erl12
-rw-r--r--test/crash_protocol.erl7
3 files changed, 27 insertions, 1 deletions
diff --git a/src/ranch_conns_sup.erl b/src/ranch_conns_sup.erl
index f3a6a0c..008b02b 100644
--- a/src/ranch_conns_sup.erl
+++ b/src/ranch_conns_sup.erl
@@ -111,7 +111,7 @@ loop(State=#state{parent=Parent, ref=Ref, conn_type=ConnType,
max_conns=MaxConns}, CurConns, NbChildren, Sleepers) ->
receive
{?MODULE, start_protocol, To, Socket} ->
- case Protocol:start_link(Ref, Socket, Transport, Opts) of
+ try Protocol:start_link(Ref, Socket, Transport, Opts) of
{ok, Pid} ->
shoot(State, CurConns, NbChildren, Sleepers, To, Socket, Pid, Pid);
{ok, SupPid, ProtocolPid} when ConnType =:= supervisor ->
@@ -124,6 +124,13 @@ loop(State=#state{parent=Parent, ref=Ref, conn_type=ConnType,
[Ref, Protocol, Ret]),
Transport:close(Socket),
loop(State, CurConns, NbChildren, Sleepers)
+ catch Class:Reason ->
+ To ! self(),
+ error_logger:error_msg(
+ "Ranch listener ~p connection process start failure; "
+ "~p:start_link/4 crashed with reason: ~p:~999999p~n",
+ [Ref, Protocol, Class, Reason]),
+ loop(State, CurConns, NbChildren, Sleepers)
end;
{?MODULE, active_connections, To, Tag} ->
To ! {Tag, CurConns},
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index af1ea5e..8c0f658 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -48,6 +48,7 @@ groups() ->
supervisor_clean_conns_sup_restart,
supervisor_clean_restart,
supervisor_conns_alive,
+ supervisor_protocol_start_link_crash,
supervisor_server_recover_state
]}].
@@ -459,6 +460,17 @@ supervisor_conns_alive(_) ->
ok = clean_traces(),
ok = ranch:stop_listener(Name).
+supervisor_protocol_start_link_crash(_) ->
+ doc("Ensure a protocol start crash does not kill all connections."),
+ Name = supervisor_protocol_start_link_crash,
+ {ok, _} = ranch:start_listener(Name, 1, ranch_tcp, [], crash_protocol, []),
+ ConnsSup = ranch_server:get_connections_sup(Name),
+ Port = ranch:get_port(Name),
+ {ok, _} = gen_tcp:connect("localhost", Port, [binary, {active, true}, {packet, raw}]),
+ receive after 500 -> ok end,
+ ConnsSup = ranch_server:get_connections_sup(Name),
+ ok = ranch:stop_listener(Name).
+
supervisor_server_recover_state(_) ->
%% Verify that if ranch_server crashes it regains its state and monitors
%% ranch_conns_sup that were previously registered.
diff --git a/test/crash_protocol.erl b/test/crash_protocol.erl
new file mode 100644
index 0000000..e584f4d
--- /dev/null
+++ b/test/crash_protocol.erl
@@ -0,0 +1,7 @@
+-module(crash_protocol).
+
+-export([start_link/4]).
+
+-spec start_link(_, _, _, _) -> no_return().
+start_link(_, _, _, _) ->
+ exit(crash).