aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cowboy_acceptor.erl30
-rw-r--r--src/cowboy_acceptors_sup.erl3
2 files changed, 23 insertions, 10 deletions
diff --git a/src/cowboy_acceptor.erl b/src/cowboy_acceptor.erl
index f27f446..9bcc733 100644
--- a/src/cowboy_acceptor.erl
+++ b/src/cowboy_acceptor.erl
@@ -13,28 +13,31 @@
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-module(cowboy_acceptor).
--export([start_link/5]). %% API.
--export([acceptor/5]). %% Internal.
+-export([start_link/6]). %% API.
+-export([acceptor/6]). %% Internal.
%% API.
-spec start_link(LSocket::inet:socket(), Transport::module(),
- Protocol::module(), Opts::term(), ReqsSup::pid()) -> {ok, Pid::pid()}.
-start_link(LSocket, Transport, Protocol, Opts, ReqsSup) ->
+ Protocol::module(), Opts::term(),
+ MaxConns::non_neg_integer(), ReqsSup::pid()) -> {ok, Pid::pid()}.
+start_link(LSocket, Transport, Protocol, Opts, MaxConns, ReqsSup) ->
Pid = spawn_link(?MODULE, acceptor,
- [LSocket, Transport, Protocol, Opts, ReqsSup]),
+ [LSocket, Transport, Protocol, Opts, MaxConns, ReqsSup]),
{ok, Pid}.
%% Internal.
-spec acceptor(LSocket::inet:socket(), Transport::module(),
- Protocol::module(), Opts::term(), ReqsSup::pid()) -> no_return().
-acceptor(LSocket, Transport, Protocol, Opts, ReqsSup) ->
+ Protocol::module(), Opts::term(),
+ MaxConns::non_neg_integer(), ReqsSup::pid()) -> no_return().
+acceptor(LSocket, Transport, Protocol, Opts, MaxConns, ReqsSup) ->
case Transport:accept(LSocket, 2000) of
{ok, CSocket} ->
{ok, Pid} = supervisor:start_child(ReqsSup,
[CSocket, Transport, Protocol, Opts]),
- Transport:controlling_process(CSocket, Pid);
+ Transport:controlling_process(CSocket, Pid),
+ limit_reqs(MaxConns, ReqsSup);
{error, timeout} ->
ignore;
{error, _Reason} ->
@@ -42,4 +45,13 @@ acceptor(LSocket, Transport, Protocol, Opts, ReqsSup) ->
%% we may want to try and listen again on the port?
ignore
end,
- ?MODULE:acceptor(LSocket, Transport, Protocol, Opts, ReqsSup).
+ ?MODULE:acceptor(LSocket, Transport, Protocol, Opts, MaxConns, ReqsSup).
+
+-spec limit_reqs(MaxConns::non_neg_integer(), ReqsSup::pid()) -> ok.
+limit_reqs(MaxConns, ReqsSup) ->
+ Counts = supervisor:count_children(ReqsSup),
+ Active = lists:keyfind(active, 1, Counts),
+ case Active < MaxConns of
+ true -> ok;
+ false -> timer:sleep(1)
+ end.
diff --git a/src/cowboy_acceptors_sup.erl b/src/cowboy_acceptors_sup.erl
index 3fbffb1..f5b2de3 100644
--- a/src/cowboy_acceptors_sup.erl
+++ b/src/cowboy_acceptors_sup.erl
@@ -32,8 +32,9 @@ start_link(NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts, ReqsPid) ->
-spec init(list(term())) -> term(). %% @todo These specs should be improved.
init([NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts, ReqsPid]) ->
{ok, LSocket} = Transport:listen(TransOpts),
+ MaxConns = proplists:get_value(max_connections, TransOpts, 1024),
Procs = [{{acceptor, self(), N}, {cowboy_acceptor, start_link, [
- LSocket, Transport, Protocol, ProtoOpts, ReqsPid
+ LSocket, Transport, Protocol, ProtoOpts, MaxConns, ReqsPid
]}, permanent, brutal_kill, worker, dynamic}
|| N <- lists:seq(1, NbAcceptors)],
{ok, {{one_for_one, 10, 10}, Procs}}.