aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ranch.erl81
-rw-r--r--src/ranch_acceptors_sup.erl11
-rw-r--r--src/ranch_listener_sup.erl4
-rw-r--r--src/ranch_server.erl41
4 files changed, 113 insertions, 24 deletions
diff --git a/src/ranch.erl b/src/ranch.erl
index 70fb64c..5af4b74 100644
--- a/src/ranch.erl
+++ b/src/ranch.erl
@@ -17,17 +17,23 @@
-export([start_listener/5]).
-export([start_listener/6]).
-export([stop_listener/1]).
+-export([suspend_listener/1]).
+-export([resume_listener/1]).
-export([child_spec/5]).
-export([child_spec/6]).
-export([accept_ack/1]).
-export([remove_connection/1]).
+-export([get_status/1]).
-export([get_addr/1]).
-export([get_port/1]).
-export([get_max_connections/1]).
-export([set_max_connections/2]).
+-export([get_transport_options/1]).
+-export([set_transport_options/2]).
-export([get_protocol_options/1]).
-export([set_protocol_options/2]).
-export([info/0]).
+-export([info/1]).
-export([procs/2]).
-export([filter_options/3]).
-export([set_option_default/3]).
@@ -110,6 +116,37 @@ stop_listener(Ref) ->
{error, Reason}
end.
+-spec suspend_listener(ref()) -> ok | {error, term()}.
+suspend_listener(Ref) ->
+ case get_status(Ref) of
+ running ->
+ ListenerSup = ranch_server:get_listener_sup(Ref),
+ ok = ranch_server:set_addr(Ref, {undefined, undefined}),
+ supervisor:terminate_child(ListenerSup, ranch_acceptors_sup);
+ suspended ->
+ ok
+ end.
+
+-spec resume_listener(ref()) -> ok | {error, term()}.
+resume_listener(Ref) ->
+ case get_status(Ref) of
+ running ->
+ ok;
+ suspended ->
+ ListenerSup = ranch_server:get_listener_sup(Ref),
+ Res = supervisor:restart_child(ListenerSup, ranch_acceptors_sup),
+ maybe_resumed(Res)
+ end.
+
+maybe_resumed(Error={error, {listen_error, _, Reason}}) ->
+ start_error(Reason, Error);
+maybe_resumed({ok, _}) ->
+ ok;
+maybe_resumed({ok, _, _}) ->
+ ok;
+maybe_resumed(Res) ->
+ Res.
+
-spec child_spec(ref(), module(), any(), module(), any())
-> supervisor:child_spec().
child_spec(Ref, Transport, TransOpts, Protocol, ProtoOpts) ->
@@ -137,11 +174,22 @@ remove_connection(Ref) ->
ConnsSup ! {remove_connection, Ref, self()},
ok.
--spec get_addr(ref()) -> {inet:ip_address(), inet:port_number()}.
+-spec get_status(ref()) -> running | suspended | restarting.
+get_status(Ref) ->
+ ListenerSup = ranch_server:get_listener_sup(Ref),
+ Children = supervisor:which_children(ListenerSup),
+ case lists:keyfind(ranch_acceptors_sup, 1, Children) of
+ {_, undefined, _, _} ->
+ suspended;
+ {_, AcceptorsSup, _, _} when is_pid(AcceptorsSup) ->
+ running
+ end.
+
+-spec get_addr(ref()) -> {inet:ip_address(), inet:port_number()} | {undefined, undefined}.
get_addr(Ref) ->
ranch_server:get_addr(Ref).
--spec get_port(ref()) -> inet:port_number().
+-spec get_port(ref()) -> inet:port_number() | undefined.
get_port(Ref) ->
{_, Port} = get_addr(Ref),
Port.
@@ -154,6 +202,19 @@ get_max_connections(Ref) ->
set_max_connections(Ref, MaxConnections) ->
ranch_server:set_max_connections(Ref, MaxConnections).
+-spec get_transport_options(ref()) -> any().
+get_transport_options(Ref) ->
+ ranch_server:get_transport_options(Ref).
+
+-spec set_transport_options(ref(), any()) -> ok | {error, running}.
+set_transport_options(Ref, TransOpts) ->
+ case get_status(Ref) of
+ suspended ->
+ ok = ranch_server:set_transport_options(Ref, TransOpts);
+ running ->
+ {error, running}
+ end.
+
-spec get_protocol_options(ref()) -> any().
get_protocol_options(Ref) ->
ranch_server:get_protocol_options(Ref).
@@ -167,14 +228,22 @@ info() ->
[{Ref, listener_info(Ref, Pid)}
|| {Ref, Pid} <- ranch_server:get_listener_sups()].
+-spec info(ref()) -> [{atom(), any()}].
+info(Ref) ->
+ Pid = ranch_server:get_listener_sup(Ref),
+ listener_info(Ref, Pid).
+
listener_info(Ref, Pid) ->
- [_, NumAcceptors, Transport, TransOpts, Protocol, _] = ranch_server:get_listener_start_args(Ref),
+ [_, NumAcceptors, Transport, _, Protocol, _] = ranch_server:get_listener_start_args(Ref),
ConnsSup = ranch_server:get_connections_sup(Ref),
+ Status = get_status(Ref),
{IP, Port} = get_addr(Ref),
MaxConns = get_max_connections(Ref),
+ TransOpts = ranch_server:get_transport_options(Ref),
ProtoOpts = get_protocol_options(Ref),
[
{pid, Pid},
+ {status, Status},
{ip, IP},
{port, Port},
{num_acceptors, NumAcceptors},
@@ -197,7 +266,11 @@ procs1(Ref, Sup) ->
ListenerSup = ranch_server:get_listener_sup(Ref),
{_, SupPid, _, _} = lists:keyfind(Sup, 1,
supervisor:which_children(ListenerSup)),
- [Pid || {_, Pid, _, _} <- supervisor:which_children(SupPid)].
+ try
+ [Pid || {_, Pid, _, _} <- supervisor:which_children(SupPid)]
+ catch exit:{noproc, _} when Sup =:= ranch_acceptors_sup ->
+ []
+ end.
-spec filter_options([inet | inet6 | {atom(), any()} | {raw, any(), any(), any()}],
[atom()], Acc) -> Acc when Acc :: [any()].
diff --git a/src/ranch_acceptors_sup.erl b/src/ranch_acceptors_sup.erl
index f4b2fd8..9e39f2d 100644
--- a/src/ranch_acceptors_sup.erl
+++ b/src/ranch_acceptors_sup.erl
@@ -15,16 +15,17 @@
-module(ranch_acceptors_sup).
-behaviour(supervisor).
--export([start_link/4]).
+-export([start_link/3]).
-export([init/1]).
--spec start_link(ranch:ref(), non_neg_integer(), module(), any())
+-spec start_link(ranch:ref(), non_neg_integer(), module())
-> {ok, pid()}.
-start_link(Ref, NumAcceptors, Transport, TransOpts) ->
- supervisor:start_link(?MODULE, [Ref, NumAcceptors, Transport, TransOpts]).
+start_link(Ref, NumAcceptors, Transport) ->
+ supervisor:start_link(?MODULE, [Ref, NumAcceptors, Transport]).
-init([Ref, NumAcceptors, Transport, TransOpts]) ->
+init([Ref, NumAcceptors, Transport]) ->
ConnsSup = ranch_server:get_connections_sup(Ref),
+ TransOpts = ranch_server:get_transport_options(Ref),
LSocket = case proplists:get_value(socket, TransOpts) of
undefined ->
TransOpts2 = proplists:delete(ack_timeout,
diff --git a/src/ranch_listener_sup.erl b/src/ranch_listener_sup.erl
index d3bc59d..502df44 100644
--- a/src/ranch_listener_sup.erl
+++ b/src/ranch_listener_sup.erl
@@ -22,7 +22,7 @@
-> {ok, pid()}.
start_link(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) ->
MaxConns = proplists:get_value(max_connections, TransOpts, 1024),
- ranch_server:set_new_listener_opts(Ref, MaxConns, ProtoOpts,
+ ranch_server:set_new_listener_opts(Ref, MaxConns, TransOpts, ProtoOpts,
[Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts]),
supervisor:start_link(?MODULE, {
Ref, NumAcceptors, Transport, TransOpts, Protocol
@@ -38,7 +38,7 @@ init({Ref, NumAcceptors, Transport, TransOpts, Protocol}) ->
[Ref, ConnType, Shutdown, Transport, AckTimeout, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup]},
{ranch_acceptors_sup, {ranch_acceptors_sup, start_link,
- [Ref, NumAcceptors, Transport, TransOpts]},
+ [Ref, NumAcceptors, Transport]},
permanent, infinity, supervisor, [ranch_acceptors_sup]}
],
{ok, {{rest_for_one, 1, 5}, ChildSpecs}}.
diff --git a/src/ranch_server.erl b/src/ranch_server.erl
index 89c508c..80f82d6 100644
--- a/src/ranch_server.erl
+++ b/src/ranch_server.erl
@@ -17,7 +17,7 @@
%% API.
-export([start_link/0]).
--export([set_new_listener_opts/4]).
+-export([set_new_listener_opts/5]).
-export([cleanup_listener_opts/1]).
-export([set_connections_sup/2]).
-export([get_connections_sup/1]).
@@ -29,6 +29,8 @@
-export([get_addr/1]).
-export([set_max_connections/2]).
-export([get_max_connections/1]).
+-export([set_transport_options/2]).
+-export([get_transport_options/1]).
-export([set_protocol_options/2]).
-export([get_protocol_options/1]).
-export([get_listener_start_args/1]).
@@ -55,15 +57,16 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
--spec set_new_listener_opts(ranch:ref(), ranch:max_conns(), any(), [any()]) -> ok.
-set_new_listener_opts(Ref, MaxConns, ProtoOpts, StartArgs) ->
- gen_server:call(?MODULE, {set_new_listener_opts, Ref, MaxConns, ProtoOpts, StartArgs}).
+-spec set_new_listener_opts(ranch:ref(), ranch:max_conns(), any(), any(), [any()]) -> ok.
+set_new_listener_opts(Ref, MaxConns, TransOpts, ProtoOpts, StartArgs) ->
+ gen_server:call(?MODULE, {set_new_listener_opts, Ref, MaxConns, TransOpts, ProtoOpts, StartArgs}).
-spec cleanup_listener_opts(ranch:ref()) -> ok.
cleanup_listener_opts(Ref) ->
_ = ets:delete(?TAB, {addr, Ref}),
_ = ets:delete(?TAB, {max_conns, Ref}),
- _ = ets:delete(?TAB, {opts, Ref}),
+ _ = ets:delete(?TAB, {trans_opts, Ref}),
+ _ = ets:delete(?TAB, {proto_opts, Ref}),
_ = ets:delete(?TAB, {listener_start_args, Ref}),
%% We also remove the pid of the connections supervisor.
%% Depending on the timing, it might already have been deleted
@@ -103,11 +106,11 @@ get_listener_sup(Ref) ->
get_listener_sups() ->
[{Ref, Pid} || [Ref, Pid] <- ets:match(?TAB, {{listener_sup, '$1'}, '$2'})].
--spec set_addr(ranch:ref(), {inet:ip_address(), inet:port_number()}) -> ok.
+-spec set_addr(ranch:ref(), {inet:ip_address(), inet:port_number()} | {undefined, undefined}) -> ok.
set_addr(Ref, Addr) ->
gen_server:call(?MODULE, {set_addr, Ref, Addr}).
--spec get_addr(ranch:ref()) -> {inet:ip_address(), inet:port_number()}.
+-spec get_addr(ranch:ref()) -> {inet:ip_address(), inet:port_number()} | {undefined, undefined}.
get_addr(Ref) ->
ets:lookup_element(?TAB, {addr, Ref}, 2).
@@ -119,13 +122,21 @@ set_max_connections(Ref, MaxConnections) ->
get_max_connections(Ref) ->
ets:lookup_element(?TAB, {max_conns, Ref}, 2).
+-spec set_transport_options(ranch:ref(), any()) -> ok.
+set_transport_options(Ref, TransOpts) ->
+ gen_server:call(?MODULE, {set_trans_opts, Ref, TransOpts}).
+
+-spec get_transport_options(ranch:ref()) -> any().
+get_transport_options(Ref) ->
+ ets:lookup_element(?TAB, {trans_opts, Ref}, 2).
+
-spec set_protocol_options(ranch:ref(), any()) -> ok.
set_protocol_options(Ref, ProtoOpts) ->
- gen_server:call(?MODULE, {set_opts, Ref, ProtoOpts}).
+ gen_server:call(?MODULE, {set_proto_opts, Ref, ProtoOpts}).
-spec get_protocol_options(ranch:ref()) -> any().
get_protocol_options(Ref) ->
- ets:lookup_element(?TAB, {opts, Ref}, 2).
+ ets:lookup_element(?TAB, {proto_opts, Ref}, 2).
-spec get_listener_start_args(ranch:ref()) -> [any()].
get_listener_start_args(Ref) ->
@@ -144,9 +155,10 @@ init([]) ->
[Ref, Pid] <- ets:match(?TAB, {{listener_sup, '$1'}, '$2'})],
{ok, #state{monitors=ConnMonitors++ListenerMonitors}}.
-handle_call({set_new_listener_opts, Ref, MaxConns, ProtoOpts, StartArgs}, _, State) ->
+handle_call({set_new_listener_opts, Ref, MaxConns, TransOpts, ProtoOpts, StartArgs}, _, State) ->
ets:insert(?TAB, {{max_conns, Ref}, MaxConns}),
- ets:insert(?TAB, {{opts, Ref}, ProtoOpts}),
+ ets:insert(?TAB, {{trans_opts, Ref}, TransOpts}),
+ ets:insert(?TAB, {{proto_opts, Ref}, ProtoOpts}),
ets:insert(?TAB, {{listener_start_args, Ref}, StartArgs}),
{reply, ok, State};
handle_call({set_connections_sup, Ref, Pid}, _,
@@ -177,8 +189,11 @@ handle_call({set_max_conns, Ref, MaxConns}, _, State) ->
ConnsSup = get_connections_sup(Ref),
ConnsSup ! {set_max_conns, MaxConns},
{reply, ok, State};
-handle_call({set_opts, Ref, Opts}, _, State) ->
- ets:insert(?TAB, {{opts, Ref}, Opts}),
+handle_call({set_trans_opts, Ref, Opts}, _, State) ->
+ ets:insert(?TAB, {{trans_opts, Ref}, Opts}),
+ {reply, ok, State};
+handle_call({set_proto_opts, Ref, Opts}, _, State) ->
+ ets:insert(?TAB, {{proto_opts, Ref}, Opts}),
ConnsSup = get_connections_sup(Ref),
ConnsSup ! {set_opts, Opts},
{reply, ok, State};