From d59eef5c737d0b08eb8c16c5316300e863bc935c Mon Sep 17 00:00:00 2001 From: juhlig Date: Wed, 8 May 2019 15:05:27 +0200 Subject: Add the num_conns_sups option This new option allows configuring the number of connection supervisors. The old behavior can be obtained by setting this value to 1. A value larger than num_acceptors will result in some connection supervisors not being used as the acceptors currently only use one connection supervisor. --- src/ranch.erl | 1 + src/ranch_acceptor.erl | 2 +- src/ranch_conns_sup.erl | 15 +++++++-------- src/ranch_conns_sup_sup.erl | 9 +++++---- src/ranch_listener_sup.erl | 7 ++++--- src/ranch_server.erl | 33 ++++++++++++++++++--------------- 6 files changed, 36 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/ranch.erl b/src/ranch.erl index 2290dee..6649c10 100644 --- a/src/ranch.erl +++ b/src/ranch.erl @@ -65,6 +65,7 @@ max_connections => max_conns(), logger => module(), num_acceptors => pos_integer(), + num_conns_sups => pos_integer(), shutdown => timeout() | brutal_kill, socket_opts => any() }. diff --git a/src/ranch_acceptor.erl b/src/ranch_acceptor.erl index cb34d75..2120788 100644 --- a/src/ranch_acceptor.erl +++ b/src/ranch_acceptor.erl @@ -17,7 +17,7 @@ -export([start_link/5]). -export([loop/5]). --spec start_link(ranch:ref(), non_neg_integer(), inet:socket(), module(), module()) +-spec start_link(ranch:ref(), pos_integer(), inet:socket(), module(), module()) -> {ok, pid()}. start_link(Ref, AcceptorId, LSocket, Transport, Logger) -> ConnsSup = ranch_server:get_connections_sup(Ref, AcceptorId), diff --git a/src/ranch_conns_sup.erl b/src/ranch_conns_sup.erl index 0ff12c6..171565e 100644 --- a/src/ranch_conns_sup.erl +++ b/src/ranch_conns_sup.erl @@ -34,7 +34,6 @@ -record(state, { parent = undefined :: pid(), ref :: ranch:ref(), - acceptor_id :: non_neg_integer(), conn_type :: conn_type(), shutdown :: shutdown(), transport = undefined :: module(), @@ -47,10 +46,10 @@ %% API. --spec start_link(ranch:ref(), non_neg_integer(), module(), module()) -> {ok, pid()}. -start_link(Ref, AcceptorId, Transport, Protocol) -> +-spec start_link(ranch:ref(), pos_integer(), module(), module()) -> {ok, pid()}. +start_link(Ref, Id, Transport, Protocol) -> proc_lib:start_link(?MODULE, init, - [self(), Ref, AcceptorId, Transport, Protocol]). + [self(), Ref, Id, Transport, Protocol]). %% We can safely assume we are on the same node as the supervisor. %% @@ -100,10 +99,10 @@ active_connections(SupPid) -> %% Supervisor internals. --spec init(pid(), ranch:ref(), non_neg_integer(), module(), module()) -> no_return(). -init(Parent, Ref, AcceptorId, Transport, Protocol) -> +-spec init(pid(), ranch:ref(), pos_integer(), module(), module()) -> no_return(). +init(Parent, Ref, Id, Transport, Protocol) -> process_flag(trap_exit, true), - ok = ranch_server:set_connections_sup(Ref, AcceptorId, self()), + ok = ranch_server:set_connections_sup(Ref, Id, self()), MaxConns = ranch_server:get_max_connections(Ref), TransOpts = ranch_server:get_transport_options(Ref), ConnType = maps:get(connection_type, TransOpts, worker), @@ -112,7 +111,7 @@ init(Parent, Ref, AcceptorId, 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, acceptor_id=AcceptorId, conn_type=ConnType, + loop(#state{parent=Parent, ref=Ref, conn_type=ConnType, shutdown=Shutdown, transport=Transport, protocol=Protocol, opts=ProtoOpts, handshake_timeout=HandshakeTimeout, max_conns=MaxConns, logger=Logger}, 0, 0, []). diff --git a/src/ranch_conns_sup_sup.erl b/src/ranch_conns_sup_sup.erl index 423c5db..142b9de 100644 --- a/src/ranch_conns_sup_sup.erl +++ b/src/ranch_conns_sup_sup.erl @@ -19,16 +19,17 @@ -export([start_link/4]). -export([init/1]). -start_link(Ref, NumAcceptors, Transport, Protocol) -> +-spec start_link(ranch:ref(), pos_integer(), ranch:opts(), module()) -> {ok, pid()}. +start_link(Ref, NumConnsSups, Transport, Protocol) -> ok = ranch_server:cleanup_connections_sups(Ref), supervisor:start_link(?MODULE, { - Ref, NumAcceptors, Transport, Protocol + Ref, NumConnsSups, Transport, Protocol }). -init({Ref, NumAcceptors, Transport, Protocol}) -> +init({Ref, NumConnsSups, 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)], + || N <- lists:seq(1, NumConnsSups)], {ok, {{one_for_one, 1, 5}, ChildSpecs}}. diff --git a/src/ranch_listener_sup.erl b/src/ranch_listener_sup.erl index a4cc995..bf533a9 100644 --- a/src/ranch_listener_sup.erl +++ b/src/ranch_listener_sup.erl @@ -22,18 +22,19 @@ -> {ok, pid()}. start_link(Ref, Transport, TransOpts, Protocol, ProtoOpts) -> NumAcceptors = maps:get(num_acceptors, TransOpts, 10), + NumConnsSups = maps:get(num_conns_sups, TransOpts, NumAcceptors), 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, NumAcceptors, Transport, Protocol + Ref, NumAcceptors, NumConnsSups, Transport, Protocol }). -init({Ref, NumAcceptors, Transport, Protocol}) -> +init({Ref, NumAcceptors, NumConnsSups, Transport, Protocol}) -> ok = ranch_server:set_listener_sup(Ref, self()), ChildSpecs = [ {ranch_conns_sup_sup, {ranch_conns_sup_sup, start_link, - [Ref, NumAcceptors, Transport, Protocol]}, + [Ref, NumConnsSups, Transport, Protocol]}, permanent, infinity, supervisor, [ranch_conns_sup_sup]}, {ranch_acceptors_sup, {ranch_acceptors_sup, start_link, [Ref, NumAcceptors, Transport]}, diff --git a/src/ranch_server.erl b/src/ranch_server.erl index 9116217..b77b935 100644 --- a/src/ranch_server.erl +++ b/src/ranch_server.erl @@ -88,22 +88,25 @@ cleanup_connections_sups(Ref) -> ok. -spec set_connections_sup(ranch:ref(), non_neg_integer(), pid()) -> ok. -set_connections_sup(Ref, AcceptorId, Pid) -> - gen_server:call(?MODULE, {set_connections_sup, Ref, AcceptorId, Pid}). +set_connections_sup(Ref, Id, Pid) -> + gen_server:call(?MODULE, {set_connections_sup, Ref, Id, Pid}). --spec get_connections_sup(ranch:ref(), non_neg_integer()) -> pid(). -get_connections_sup(Ref, AcceptorId) -> - ets:lookup_element(?TAB, {conns_sup, Ref, AcceptorId}, 2). +-spec get_connections_sup(ranch:ref(), pos_integer()) -> pid(). +get_connections_sup(Ref, Id) -> + ConnsSups = get_connections_sups(Ref), + NConnsSups = length(ConnsSups), + {_, Pid} = lists:keyfind((Id rem NConnsSups) + 1, 1, ConnsSups), + Pid. --spec get_connections_sups(ranch:ref()) -> [{non_neg_integer(), pid()}]. +-spec get_connections_sups(ranch:ref()) -> [{pos_integer(), pid()}]. get_connections_sups(Ref) -> - [{AcceptorId, Pid} || - [AcceptorId, Pid] <- ets:match(?TAB, {{conns_sup, Ref, '$1'}, '$2'})]. + [{Id, Pid} || + [Id, Pid] <- ets:match(?TAB, {{conns_sup, Ref, '$1'}, '$2'})]. --spec get_connections_sups() -> [{ranch:ref(), non_neg_integer(), pid()}]. +-spec get_connections_sups() -> [{ranch:ref(), pos_integer(), pid()}]. get_connections_sups() -> - [{Ref, AcceptorId, Pid} || - [Ref, AcceptorId, Pid] <- ets:match(?TAB, {{conns_sup, '$1', '$2'}, '$3'})]. + [{Ref, Id, Pid} || + [Ref, Id, Pid] <- ets:match(?TAB, {{conns_sup, '$1', '$2'}, '$3'})]. -spec set_listener_sup(ranch:ref(), pid()) -> ok. set_listener_sup(Ref, Pid) -> @@ -165,8 +168,8 @@ count_connections(Ref) -> %% gen_server. init([]) -> - ConnMonitors = [{{erlang:monitor(process, Pid), Pid}, {conns_sup, Ref, AcceptorId}} || - [Ref, AcceptorId, Pid] <- ets:match(?TAB, {{conns_sup, '$1', '$2'}, '$3'})], + ConnMonitors = [{{erlang:monitor(process, Pid), Pid}, {conns_sup, Ref, Id}} || + [Ref, Id, Pid] <- ets:match(?TAB, {{conns_sup, '$1', '$2'}, '$3'})], ListenerMonitors = [{{erlang:monitor(process, Pid), Pid}, {listener_sup, Ref}} || [Ref, Pid] <- ets:match(?TAB, {{listener_sup, '$1'}, '$2'})], {ok, #state{monitors=ConnMonitors++ListenerMonitors}}. @@ -177,8 +180,8 @@ handle_call({set_new_listener_opts, Ref, MaxConns, TransOpts, ProtoOpts, StartAr ets:insert_new(?TAB, {{proto_opts, Ref}, ProtoOpts}), ets:insert_new(?TAB, {{listener_start_args, Ref}, StartArgs}), {reply, ok, State}; -handle_call({set_connections_sup, Ref, AcceptorId, Pid}, _, State0) -> - State = set_monitored_process({conns_sup, Ref, AcceptorId}, Pid, State0), +handle_call({set_connections_sup, Ref, Id, Pid}, _, State0) -> + State = set_monitored_process({conns_sup, Ref, Id}, Pid, State0), {reply, ok, State}; handle_call({set_listener_sup, Ref, Pid}, _, State0) -> State = set_monitored_process({listener_sup, Ref}, Pid, State0), -- cgit v1.2.3