aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ranch_server.erl4
-rw-r--r--test/acceptor_SUITE.erl33
2 files changed, 35 insertions, 2 deletions
diff --git a/src/ranch_server.erl b/src/ranch_server.erl
index d827ae2..7557d53 100644
--- a/src/ranch_server.erl
+++ b/src/ranch_server.erl
@@ -114,7 +114,9 @@ count_connections(Ref) ->
%% @private
init([]) ->
- {ok, #state{}}.
+ Monitors = [{{erlang:monitor(process, Pid), Pid}, Ref} ||
+ [Ref, Pid] <- ets:match(?TAB, {{conns_sup, '$1'}, '$2'})],
+ {ok, #state{monitors=Monitors}}.
%% @private
handle_call({set_new_listener_opts, Ref, MaxConns, Opts}, _, State) ->
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index 02a5d79..ca8c856 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -48,6 +48,7 @@
-export([supervisor_clean_restart/1]).
-export([supervisor_clean_child_restart/1]).
-export([supervisor_conns_alive/1]).
+-export([supervisor_server_recover_state/1]).
%% ct.
@@ -75,7 +76,8 @@ groups() ->
]}, {supervisor, [
supervisor_clean_restart,
supervisor_clean_child_restart,
- supervisor_conns_alive
+ supervisor_conns_alive,
+ supervisor_server_recover_state
]}].
init_per_suite(Config) ->
@@ -468,6 +470,35 @@ supervisor_conns_alive(_) ->
ok = clean_traces(),
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.
+ Name = supervisor_server_recover_state,
+ {ok, _} = ranch:start_listener(Name, 1,
+ ranch_tcp, [{port, 0}], echo_protocol, []),
+ _ = erlang:trace(new, true, [call]),
+ 1 = erlang:trace_pattern({ranch_server, init, 1},
+ [{'_', [], [{return_trace}]}], [global]),
+ ConnsSup = ranch_server:get_connections_sup(Name),
+ ServerPid = erlang:whereis(ranch_server),
+ {monitors, Monitors} = erlang:process_info(ServerPid, monitors),
+ erlang:exit(ServerPid, kill),
+ receive
+ {trace, ServerPid2, return_from, {ranch_server, init, 1}, _Result} ->
+ {monitors, Monitors2} = erlang:process_info(ServerPid2, monitors),
+ %% Check that ranch_server is monitoring the same processes.
+ true = (lists:usort(Monitors) == lists:usort(Monitors2))
+ after
+ 1000 ->
+ error(timeout)
+ end,
+ ConnsSup = ranch_server:get_connections_sup(Name),
+ ranch:stop_listener(Name),
+ %% Check ranch_server has removed the ranch_conns_sup.
+ {'EXIT', {badarg, _}} = (catch ranch_server:get_connections_sup(Name)),
+ _ = erlang:trace(all, false, [all]),
+ ok = clean_traces().
+
%% Utility functions.
connect_loop(_, 0, _) ->