From ee1f82782835096208059ea14d52bf2cc0283323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 20 Aug 2015 16:05:50 +0200 Subject: Ensure ranch_conns_sup doesn't crash on protocol start crash --- src/ranch_conns_sup.erl | 9 ++++++++- test/acceptor_SUITE.erl | 12 ++++++++++++ test/crash_protocol.erl | 7 +++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/crash_protocol.erl 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). -- cgit v1.2.3