diff options
-rw-r--r-- | src/ranch_server.erl | 4 | ||||
-rw-r--r-- | test/acceptor_SUITE.erl | 33 |
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 db9d4ff..e784428 100644 --- a/test/acceptor_SUITE.erl +++ b/test/acceptor_SUITE.erl @@ -47,6 +47,7 @@ -export([supervisor_clean_restart/1]). -export([supervisor_clean_child_restart/1]). -export([supervisor_conns_alive/1]). +-export([supervisor_server_recover_state/1]). %% ct. @@ -73,7 +74,8 @@ groups() -> ]}, {supervisor, [ supervisor_clean_restart, supervisor_clean_child_restart, - supervisor_conns_alive + supervisor_conns_alive, + supervisor_server_recover_state ]}]. init_per_suite(Config) -> @@ -439,6 +441,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, _) -> |