Current section

Files

Jump to
amoc src throttle amoc_throttle_pool.erl
Raw

src/throttle/amoc_throttle_pool.erl

%% @private
%% @see amoc_throttle
%% @copyright 2024 Erlang Solutions Ltd.
-module(amoc_throttle_pool).
-behaviour(supervisor).
-export([start_process_pool/4]).
-export([start_link/4, init/1]).
-spec start_process_pool(
amoc_throttle:name(),
amoc_throttle:interval(),
amoc_throttle:rate(),
pos_integer()
) -> ok | error.
start_process_pool(Name, Interval, Rate, NoOfProcesses) ->
{ok, _} = supervisor:start_child(amoc_throttle_pooler, [Name, Interval, Rate, NoOfProcesses]),
ok.
-spec start_link(
amoc_throttle:name(),
amoc_throttle:interval(),
amoc_throttle:rate(),
pos_integer()
) -> {ok, Pid :: pid()}.
start_link(Name, Interval, Rate, NoOfProcesses) when NoOfProcesses > 0 ->
supervisor:start_link(?MODULE, {Name, Interval, Rate, NoOfProcesses}).
-spec init({amoc_throttle:name(), amoc_throttle:rate(), amoc_throttle:interval(), pos_integer()}) ->
{ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
init({Name, Interval, Rate, NoOfProcesses}) ->
RatesPerProcess = calculate_rate_per_process(Rate, NoOfProcesses),
Tags = lists:seq(1, NoOfProcesses),
Children = [
#{id => {amoc_throttle_process, Name, N},
start => {amoc_throttle_process, start_link, [Name, Interval, RatePerProcess]},
type => worker,
shutdown => timer:seconds(5),
restart => transient,
modules => [amoc_throttle_process]
}
|| {RatePerProcess, N} <- lists:zip(RatesPerProcess, Tags)
],
SupFlags = #{strategy => one_for_one, intensity => 0},
{ok, {SupFlags, Children}}.
%% Helpers
calculate_rate_per_process(Rate, NoOfProcesses) ->
calculate_rate_per_process([], Rate, NoOfProcesses).
calculate_rate_per_process(Acc, Rate, 1) ->
[Rate | Acc];
calculate_rate_per_process(Acc, Rate, N) when is_integer(N), N > 1 ->
ProcessRate = Rate div N,
calculate_rate_per_process([ProcessRate | Acc], Rate - ProcessRate, N - 1).