Skip to content

Commit

Permalink
Draft: stop_listener in ranch_server
Browse files Browse the repository at this point in the history
  • Loading branch information
juhlig committed Jul 2, 2024
1 parent 7a3aa3b commit 1c3b4f7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 37 deletions.
38 changes: 1 addition & 37 deletions src/ranch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -193,43 +193,7 @@ start_error(_, Error) -> Error.

-spec stop_listener(ref()) -> ok | {error, not_found}.
stop_listener(Ref) ->
Parent = self(),
Tag = make_ref(),
{StopperPid, StopperMon} = spawn_monitor(fun() -> Parent ! {Tag, stop_listener1(Ref)} end),
receive
{Tag, Result} ->
demonitor(StopperMon, [flush]),
Result;
{'DOWN', StopperMon, process, StopperPid, Error} ->
{error, Error}
end.

stop_listener1(Ref) ->
TransportAndOpts = maybe_get_transport_and_opts(Ref),
case supervisor:terminate_child(ranch_sup, {ranch_listener_sup, Ref}) of
ok ->
_ = supervisor:delete_child(ranch_sup, {ranch_listener_sup, Ref}),
ranch_server:cleanup_listener_opts(Ref),
stop_listener2(TransportAndOpts);
{error, _} = Error ->
Error
end.

stop_listener2({Transport, TransOpts}) ->
Transport:cleanup(TransOpts),
ok;
stop_listener2(undefined) ->
ok.

maybe_get_transport_and_opts(Ref) ->
try
[_, Transport, _, _, _] = ranch_server:get_listener_start_args(Ref),
TransOpts = get_transport_options(Ref),
{Transport, TransOpts}
catch
error:badarg ->
undefined
end.
ranch_server:stop_listener(Ref).

-spec suspend_listener(ref()) -> ok | {error, any()}.
suspend_listener(Ref) ->
Expand Down
43 changes: 43 additions & 0 deletions src/ranch_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
-export([get_protocol_options/1]).
-export([get_listener_start_args/1]).
-export([count_connections/1]).
-export([stop_listener/1]).

%% gen_server.
-export([init/1]).
Expand Down Expand Up @@ -180,6 +181,10 @@ count_connections(Ref) ->
0,
get_connections_sups(Ref)).

-spec stop_listener(ranch:ref()) -> ok | {error, term()}.
stop_listener(Ref) ->
gen_server:call(?MODULE, {stop_listener, Ref}).

%% gen_server.

-spec init([]) -> {ok, #state{}}.
Expand Down Expand Up @@ -220,6 +225,14 @@ handle_call({set_proto_opts, Ref, Opts}, _, State) ->
ets:insert(?TAB, {{proto_opts, Ref}, Opts}),
_ = [ConnsSup ! {set_protocol_options, Opts} || {_, ConnsSup} <- get_connections_sups(Ref)],
{reply, ok, State};
handle_call({stop_listener, Ref}, _, State) ->
Reply = try
do_stop_listener(Ref)
catch
_:Reason ->
{error, Reason}
end,
{reply, Reply, State};
handle_call(_Request, _From, State) ->
{reply, ignore, State}.

Expand Down Expand Up @@ -277,3 +290,33 @@ set_monitored_process(Key, Pid, State=#state{monitors=Monitors0}) ->
%% Finally we start monitoring this new process.
MonitorRef = erlang:monitor(process, Pid),
State#state{monitors=[{{MonitorRef, Pid}, Key}|Monitors]}.

do_stop_listener(Ref) ->
do_stop_listener1(Ref).

do_stop_listener1(Ref) ->
TransportAndOpts = try
[_, Transport, _, _, _] = get_listener_start_args(Ref),
TransOpts = get_transport_options(Ref),
{Transport, TransOpts}
catch
error:badarg ->
undefined
end,
do_stop_listener2(Ref, TransportAndOpts).

do_stop_listener2(Ref, TransportAndOpts) ->
case supervisor:terminate_child(ranch_sup, {ranch_listener_sup, Ref}) of
ok ->
_ = supervisor:delete_child(ranch_sup, {ranch_listener_sup, Ref}),
_ = cleanup_listener_opts(Ref),
do_stop_listener3(TransportAndOpts);
{error, _} = Error ->
Error
end.

do_stop_listener3(undefined) ->
ok;
do_stop_listener3({Transport, TransOpts}) ->
_ = Transport:cleanup(TransOpts),
ok.

0 comments on commit 1c3b4f7

Please sign in to comment.