Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

acceptor-conns_sup pairs #198

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ebin/ranch.app
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{application, 'ranch', [
{description, "Socket acceptor pool for TCP protocols."},
{vsn, "1.7.1"},
{modules, ['ranch','ranch_acceptor','ranch_acceptors_sup','ranch_app','ranch_conns_sup','ranch_crc32c','ranch_listener_sup','ranch_protocol','ranch_proxy_header','ranch_server','ranch_ssl','ranch_sup','ranch_tcp','ranch_transport']},
{modules, ['ranch','ranch_acceptor','ranch_acceptors_sup','ranch_app','ranch_conns_sup','ranch_conns_sup_sup','ranch_crc32c','ranch_listener_sup','ranch_protocol','ranch_proxy_header','ranch_server','ranch_ssl','ranch_sup','ranch_tcp','ranch_transport']},
{registered, [ranch_sup,ranch_server]},
{applications, [kernel,stdlib,ssl]},
{mod, {ranch_app, []}},
Expand Down
48 changes: 32 additions & 16 deletions src/ranch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,10 @@ recv_proxy_header(Ref, Timeout) ->

-spec remove_connection(ref()) -> ok.
remove_connection(Ref) ->
ConnsSup = ranch_server:get_connections_sup(Ref),
ConnsSup ! {remove_connection, Ref, self()},
ListenerSup = ranch_server:get_listener_sup(Ref),
{_, ConnsSupSup, _, _} = lists:keyfind(ranch_conns_sup_sup, 1,
supervisor:which_children(ListenerSup)),
_ = [ConnsSup ! {remove_connection, Ref, self()} || {_, ConnsSup, _, _} <- supervisor:which_children(ConnsSupSup)],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many lines are too long, for example this one. Please try to limit to around 100 columns. (Basically if it's not fully visible on the Github UI it's probably too long.)

ok.

-spec get_status(ref()) -> running | suspended.
Expand All @@ -279,6 +281,14 @@ get_port(Ref) ->
{_, Port} = get_addr(Ref),
Port.

-spec get_connections(ref(), active|all) -> non_neg_integer().
get_connections(Ref, active) ->
SupCounts = [ranch_conns_sup:active_connections(ConnsSup) || {_, ConnsSup} <- ranch_server:get_connections_sups(Ref)],
lists:sum(SupCounts);
get_connections(Ref, all) ->
SupCounts = [proplists:get_value(active, supervisor:count_children(ConnsSup)) || {_, ConnsSup} <- ranch_server:get_connections_sups(Ref)],
lists:sum(SupCounts).

-spec get_max_connections(ref()) -> max_conns().
get_max_connections(Ref) ->
ranch_server:get_max_connections(Ref).
Expand Down Expand Up @@ -321,7 +331,6 @@ info(Ref) ->

listener_info(Ref, Pid) ->
[_, 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),
Expand All @@ -333,29 +342,37 @@ listener_info(Ref, Pid) ->
{ip, IP},
{port, Port},
{max_connections, MaxConns},
{active_connections, ranch_conns_sup:active_connections(ConnsSup)},
{all_connections, proplists:get_value(active, supervisor:count_children(ConnsSup))},
{active_connections, get_connections(Ref, active)},
{all_connections, get_connections(Ref, all)},
{transport, Transport},
{transport_options, TransOpts},
{protocol, Protocol},
{protocol_options, ProtoOpts}
].

-spec procs(ref(), acceptors | connections) -> [pid()].
procs(Ref, acceptors) ->
procs1(Ref, ranch_acceptors_sup);
procs(Ref, connections) ->
procs1(Ref, ranch_conns_sup).

procs1(Ref, Sup) ->
procs(Ref, Type) ->
ListenerSup = ranch_server:get_listener_sup(Ref),
{_, SupPid, _, _} = lists:keyfind(Sup, 1,
procs1(ListenerSup, Type).

procs1(ListenerSup, acceptors) ->
{_, SupPid, _, _} = lists:keyfind(ranch_acceptors_sup, 1,
supervisor:which_children(ListenerSup)),
try
[Pid || {_, Pid, _, _} <- supervisor:which_children(SupPid)]
catch exit:{noproc, _} when Sup =:= ranch_acceptors_sup ->
catch exit:{noproc, _} ->
[]
end.
end;
procs1(ListenerSup, connections) ->
{_, SupSupPid, _, _} = lists:keyfind(ranch_conns_sup_sup, 1,
supervisor:which_children(ListenerSup)),
Conns=
lists:map(fun ({_, SupPid, _, _}) ->
[Pid || {_, Pid, _, _} <- supervisor:which_children(SupPid)]
end,
supervisor:which_children(SupSupPid)
),
lists:flatten(Conns).

-spec wait_for_connections
(ref(), '>' | '>=' | '==' | '=<', non_neg_integer()) -> ok;
Expand Down Expand Up @@ -387,8 +404,7 @@ validate_interval(_) -> error(badarg).

wait_for_connections_loop(Ref, Op, NumConns, Interval) ->
CurConns = try
ConnsSup = ranch_server:get_connections_sup(Ref),
proplists:get_value(active, supervisor:count_children(ConnsSup))
get_connections(Ref, all)
catch _:_ ->
0
end,
Expand Down
13 changes: 7 additions & 6 deletions src/ranch_acceptor.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,24 @@
-module(ranch_acceptor).

-export([start_link/4]).
-export([loop/4]).
-export([loop/5]).

-spec start_link(inet:socket(), module(), module(), pid())
-> {ok, pid()}.
start_link(LSocket, Transport, Logger, ConnsSup) ->
Pid = spawn_link(?MODULE, loop, [LSocket, Transport, Logger, ConnsSup]),
MonitorRef = monitor(process, ConnsSup),
Pid = spawn_link(?MODULE, loop, [LSocket, Transport, Logger, ConnsSup, MonitorRef]),
{ok, Pid}.

-spec loop(inet:socket(), module(), module(), pid()) -> no_return().
loop(LSocket, Transport, Logger, ConnsSup) ->
-spec loop(inet:socket(), module(), module(), pid(), reference()) -> no_return().
loop(LSocket, Transport, Logger, ConnsSup, MonitorRef) ->
_ = case Transport:accept(LSocket, infinity) of
{ok, CSocket} ->
case Transport:controlling_process(CSocket, ConnsSup) of
ok ->
%% This call will not return until process has been started
%% AND we are below the maximum number of connections.
ranch_conns_sup:start_protocol(ConnsSup, CSocket);
ranch_conns_sup:start_protocol(ConnsSup, MonitorRef, CSocket);
{error, _} ->
Transport:close(CSocket)
end;
Expand All @@ -51,7 +52,7 @@ loop(LSocket, Transport, Logger, ConnsSup) ->
ok
end,
flush(Logger),
?MODULE:loop(LSocket, Transport, Logger, ConnsSup).
?MODULE:loop(LSocket, Transport, Logger, ConnsSup, MonitorRef).

flush(Logger) ->
receive Msg ->
Expand Down
14 changes: 6 additions & 8 deletions src/ranch_acceptors_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,16 @@
-module(ranch_acceptors_sup).
-behaviour(supervisor).

-export([start_link/2]).
-export([start_link/3]).
-export([init/1]).

-spec start_link(ranch:ref(), module())
-spec start_link(ranch:ref(), pos_integer(), module())
-> {ok, pid()}.
start_link(Ref, Transport) ->
supervisor:start_link(?MODULE, [Ref, Transport]).
start_link(Ref, NumAcceptors, Transport) ->
supervisor:start_link(?MODULE, [Ref, NumAcceptors, Transport]).

init([Ref, Transport]) ->
ConnsSup = ranch_server:get_connections_sup(Ref),
init([Ref, NumAcceptors, Transport]) ->
TransOpts = ranch_server:get_transport_options(Ref),
NumAcceptors = maps:get(num_acceptors, TransOpts, 10),
Logger = maps:get(logger, TransOpts, error_logger),
SocketOpts = maps:get(socket_opts, TransOpts, []),
%% We temporarily put the logger in the process dictionary
Expand All @@ -45,7 +43,7 @@ init([Ref, Transport]) ->
ranch_server:set_addr(Ref, Addr),
Procs = [
{{acceptor, self(), N}, {ranch_acceptor, start_link, [
LSocket, Transport, Logger, ConnsSup
LSocket, Transport, Logger, ranch_server:get_connections_sup(Ref, N)
]}, permanent, brutal_kill, worker, []}
|| N <- lists:seq(1, NumAcceptors)],
{ok, {{one_for_one, 1, 5}, Procs}}.
Expand Down
36 changes: 25 additions & 11 deletions src/ranch_conns_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
-module(ranch_conns_sup).

%% API.
-export([start_link/3]).
-export([start_link/4]).
-export([start_protocol/2]).
-export([start_protocol/3]).
-export([active_connections/1]).

%% Supervisor internals.
-export([init/4]).
-export([init/5]).
-export([system_continue/3]).
-export([system_terminate/4]).
-export([system_code_change/4]).
Expand All @@ -34,6 +35,7 @@
-record(state, {
parent = undefined :: pid(),
ref :: ranch:ref(),
acceptor_id :: non_neg_integer(),
conn_type :: conn_type(),
shutdown :: shutdown(),
transport = undefined :: module(),
Expand All @@ -46,10 +48,10 @@

%% API.

-spec start_link(ranch:ref(), module(), module()) -> {ok, pid()}.
start_link(Ref, Transport, Protocol) ->
-spec start_link(ranch:ref(), non_neg_integer(), module(), module()) -> {ok, pid()}.
start_link(Ref, AcceptorId, Transport, Protocol) ->
proc_lib:start_link(?MODULE, init,
[self(), Ref, Transport, Protocol]).
[self(), Ref, AcceptorId, Transport, Protocol]).

%% We can safely assume we are on the same node as the supervisor.
%%
Expand All @@ -67,10 +69,22 @@ start_link(Ref, Transport, Protocol) ->
%% We do not need the reply, we only need the ok from the supervisor
%% to continue. The supervisor sends its own pid when the acceptor can
%% continue.
-spec start_protocol(pid(), reference(), inet:socket()) -> ok.
start_protocol(SupPid, MonitorRef, Socket) ->
SupPid ! {?MODULE, start_protocol, self(), Socket},
receive
SupPid ->
ok;
{'DOWN', MonitorRef, process, SupPid, Reason} ->
error(Reason)
end.

-spec start_protocol(pid(), inet:socket()) -> ok.
start_protocol(SupPid, Socket) ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not look necessary anymore, every calls are using the start_protocol/3 function.

SupPid ! {?MODULE, start_protocol, self(), Socket},
receive SupPid -> ok end.
MonitorRef = monitor(process, SupPid),
start_protocol(SupPid, MonitorRef, Socket),
demonitor(MonitorRef),
ok.

%% We can't make the above assumptions here. This function might be
%% called from anywhere.
Expand All @@ -94,10 +108,10 @@ active_connections(SupPid) ->

%% Supervisor internals.

-spec init(pid(), ranch:ref(), module(), module()) -> no_return().
init(Parent, Ref, Transport, Protocol) ->
-spec init(pid(), ranch:ref(), non_neg_integer(), module(), module()) -> no_return().
init(Parent, Ref, AcceptorId, Transport, Protocol) ->
process_flag(trap_exit, true),
ok = ranch_server:set_connections_sup(Ref, self()),
ok = ranch_server:set_connections_sup(Ref, AcceptorId, self()),
MaxConns = ranch_server:get_max_connections(Ref),
TransOpts = ranch_server:get_transport_options(Ref),
ConnType = maps:get(connection_type, TransOpts, worker),
Expand All @@ -106,7 +120,7 @@ init(Parent, Ref, Transport, Protocol) ->
Logger = maps:get(logger, TransOpts, error_logger),
ProtoOpts = ranch_server:get_protocol_options(Ref),
ok = proc_lib:init_ack(Parent, {ok, self()}),
loop(#state{parent=Parent, ref=Ref, conn_type=ConnType,
loop(#state{parent=Parent, ref=Ref, acceptor_id=AcceptorId, conn_type=ConnType,
shutdown=Shutdown, transport=Transport, protocol=Protocol,
opts=ProtoOpts, handshake_timeout=HandshakeTimeout,
max_conns=MaxConns, logger=Logger}, 0, 0, []).
Expand Down
20 changes: 20 additions & 0 deletions src/ranch_conns_sup_sup.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-module(ranch_conns_sup_sup).

-behaviour(supervisor).

-export([start_link/4]).
-export([init/1]).

start_link(Ref, NumAcceptors, Transport, Protocol) ->
ok = ranch_server:cleanup_connections_sups(Ref),
supervisor:start_link(?MODULE, {
Ref, NumAcceptors, Transport, Protocol
}).

init({Ref, NumAcceptors, Transport, Protocol}) ->
ChildSpecs = [
{{ranch_conns_sup, N}, {ranch_conns_sup, start_link,
[Ref, N, Transport, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup]}
|| N <- lists:seq(1, NumAcceptors)],
{ok, {{one_for_one, 1, 5}, ChildSpecs}}.
13 changes: 7 additions & 6 deletions src/ranch_listener_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@
-spec start_link(ranch:ref(), module(), any(), module(), any())
-> {ok, pid()}.
start_link(Ref, Transport, TransOpts, Protocol, ProtoOpts) ->
NumAcceptors = maps:get(num_acceptors, TransOpts, 10),
MaxConns = maps:get(max_connections, TransOpts, 1024),
ranch_server:set_new_listener_opts(Ref, MaxConns, TransOpts, ProtoOpts,
[Ref, Transport, TransOpts, Protocol, ProtoOpts]),
supervisor:start_link(?MODULE, {
Ref, Transport, Protocol
Ref, NumAcceptors, Transport, Protocol
}).

init({Ref, Transport, Protocol}) ->
init({Ref, NumAcceptors, Transport, Protocol}) ->
ok = ranch_server:set_listener_sup(Ref, self()),
ChildSpecs = [
{ranch_conns_sup, {ranch_conns_sup, start_link,
[Ref, Transport, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup]},
{ranch_conns_sup_sup, {ranch_conns_sup_sup, start_link,
[Ref, NumAcceptors, Transport, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup_sup]},
{ranch_acceptors_sup, {ranch_acceptors_sup, start_link,
[Ref, Transport]},
[Ref, NumAcceptors, Transport]},
permanent, infinity, supervisor, [ranch_acceptors_sup]}
],
{ok, {{rest_for_one, 1, 5}, ChildSpecs}}.
Loading