Skip to content

Commit 47e7f6c

Browse files
committed
Introduce explicit throttle API calls
1 parent 360c3a3 commit 47e7f6c

File tree

3 files changed

+294
-101
lines changed

3 files changed

+294
-101
lines changed

src/throttle/amoc_throttle.erl

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,71 @@
33
-module(amoc_throttle).
44

55
%% API
6-
-export([start/2,
7-
start/3,
8-
start/4,
9-
send/3,
10-
send/2,
11-
send_and_wait/2,
12-
wait/1,
13-
run/2,
14-
pause/1,
15-
resume/1,
16-
change_rate/3,
17-
change_rate_gradually/6,
18-
stop/1]).
19-
20-
-deprecated([{send_and_wait, 2, "use wait/1 instead"}]).
21-
22-
-define(DEFAULT_NO_PROCESSES, 10).
23-
-define(DEFAULT_INTERVAL, 60000). %% one minute
24-
-define(NONNEG_INT(N), (is_integer(N) andalso N >= 0)).
25-
-define(POS_INT(N), (is_integer(N) andalso N > 0)).
6+
-export([start/2, start/3, start/4, stop/1,
7+
send/2, send/3, send_and_wait/2, wait/1,
8+
run/2, pause/1, resume/1,
9+
change_rate/2, change_rate/3,
10+
change_rate_gradually/2, change_rate_gradually/6]).
11+
12+
-deprecated([
13+
{start, 3, "use start/2 with a config"},
14+
{start, 4, "use start/2 with a config"},
15+
{send_and_wait, 2, "use wait/1 instead"}
16+
]).
2617

2718
-type name() :: atom().
2819
-type rate() :: pos_integer().
2920
-type interval() :: non_neg_integer().
3021
%% In milliseconds, defaults to 60000 (one minute) when not given.
3122
%% An interval of 0 means no delay at all, only the number of simultaneous executions will be
3223
%% controlled, which corresponds to the number of processes started
33-
-export_type([name/0, rate/0, interval/0]).
24+
-type throttle() :: #{rate := rate(),
25+
interval := interval()}.
26+
%% Throttle unit of measurement
27+
-type config() :: #{rate := rate(),
28+
interval => interval(),
29+
parallelism => non_neg_integer()}.
30+
%% Literal throttle configuration
31+
-type gradual_rate_config() :: #{from_rate := rate(),
32+
to_rate := rate(),
33+
interval => interval(),
34+
step_interval => pos_integer(),
35+
step_size => pos_integer(),
36+
step_count => pos_integer(),
37+
duration => pos_integer()}.
38+
%% Configuration for a gradual throttle rate change
39+
%%
40+
%% `From' and `To' rates are required. `interval' defaults to 1s and `step_size' to 1 (or -1 if applies),
41+
%% that is, the throttle will be changed in increments of 1.
42+
%%
43+
%% All other values can be calculated from the provided.
44+
45+
-export_type([name/0, rate/0, interval/0, throttle/0, config/0, gradual_rate_config/0]).
3446

3547
%% @see start/4
36-
-spec start(name(), rate()) -> ok | {error, any()}.
48+
-spec start(name(), config() | rate()) -> {ok, started | already_started} | {error, any()}.
49+
start(Name, #{} = Config) ->
50+
amoc_throttle_controller:ensure_throttle_processes_started(Name, Config);
3751
start(Name, Rate) ->
38-
start(Name, Rate, ?DEFAULT_INTERVAL).
52+
amoc_throttle_controller:ensure_throttle_processes_started(Name, #{rate => Rate}).
3953

4054
%% @see start/4
41-
-spec start(name(), rate(), non_neg_integer()) -> ok | {error, any()}.
55+
-spec start(name(), rate(), non_neg_integer()) -> {ok, started | already_started} | {error, any()}.
4256
start(Name, Rate, Interval) ->
43-
start(Name, Rate, Interval, ?DEFAULT_NO_PROCESSES).
57+
Config = #{rate => Rate, interval => Interval},
58+
amoc_throttle_controller:ensure_throttle_processes_started(Name, Config).
4459

4560
%% @doc Starts the throttle mechanism for a given `Name' with a given `Rate' per `Interval'.
4661
%%
4762
%% The optional arguments are an `Interval' (default is one minute) and a ` NoOfProcesses' (default is 10).
4863
%% `Name' is needed to identify the rate as a single test can have different rates for different tasks.
4964
%% `Interval' is given in milliseconds and can be changed to a different value for convenience or higher granularity.
5065
%% It also accepts a special value of `0' which limits the number of parallel executions associated with `Name' to `Rate'.
51-
-spec start(name(), rate(), interval(), pos_integer()) -> ok | {error, any()}.
52-
start(Name, Rate, Interval, NoOfProcesses)
53-
when is_atom(Name), ?POS_INT(Rate), ?NONNEG_INT(Interval), ?POS_INT(NoOfProcesses) ->
54-
amoc_throttle_controller:ensure_throttle_processes_started(Name, Rate, Interval, NoOfProcesses);
55-
start(_Name, _Rate, _Interval, _NoOfProcesses) ->
56-
{error, invalid_throttle}.
66+
-spec start(name(), rate(), interval(), pos_integer()) ->
67+
{ok, started | already_started} | {error, any()}.
68+
start(Name, Rate, Interval, NoOfProcesses) ->
69+
Config = #{rate => Rate, interval => Interval, parallelism => NoOfProcesses},
70+
amoc_throttle_controller:ensure_throttle_processes_started(Name, Config).
5771

5872
%% @doc Pauses executions for the given `Name' as if `Rate' was set to `0'.
5973
%%
@@ -67,10 +81,15 @@ pause(Name) ->
6781
resume(Name) ->
6882
amoc_throttle_controller:resume(Name).
6983

70-
%% @doc Sets `Rate' and `Interval' for `Name' according to the given values.
84+
%% @doc Sets `Throttle' for `Name' according to the given values.
7185
%%
7286
%% Can change whether Amoc throttle limits `Name' to parallel executions or to `Rate' per `Interval',
7387
%% according to the given `Interval' value.
88+
-spec change_rate(name(), throttle()) -> ok | {error, any()}.
89+
change_rate(Name, #{rate := Rate, interval := Interval}) ->
90+
amoc_throttle_controller:change_rate(Name, Rate, Interval).
91+
92+
%% @see change_rate/2
7493
-spec change_rate(name(), rate(), interval()) -> ok | {error, any()}.
7594
change_rate(Name, Rate, Interval) ->
7695
amoc_throttle_controller:change_rate(Name, Rate, Interval).
@@ -83,12 +102,20 @@ change_rate(Name, Rate, Interval) ->
83102
%% The rate is calculated at each step in relation to the `RateInterval', which can also be `0'.
84103
%% There will be `NoOfSteps' steps, each taking `StepInterval' time in milliseconds.
85104
%%
86-
%% Be aware that, at first, the rate will be changed to `FromRate' per `RateInterval' and this is not considered a step.
105+
%% Be aware that, at first, the rate will be changed to `FromRate' per `RateInterval'
106+
%% and this is not considered a step.
107+
-spec change_rate_gradually(name(), gradual_rate_config()) ->
108+
ok | {error, any()}.
109+
change_rate_gradually(Name, Config) ->
110+
amoc_throttle_controller:change_rate_gradually(Name, Config).
111+
112+
%% @see change_rate_gradually/2
87113
-spec change_rate_gradually(name(), rate(), rate(), interval(), pos_integer(), pos_integer()) ->
88114
ok | {error, any()}.
89-
change_rate_gradually(Name, FromRate, ToRate, RateInterval, StepInterval, NoOfSteps) ->
90-
amoc_throttle_controller:change_rate_gradually(
91-
Name, FromRate, ToRate, RateInterval, StepInterval, NoOfSteps).
115+
change_rate_gradually(Name, FromRate, ToRate, RateInterval, StepInterval, StepCount) ->
116+
Config = #{from_rate => FromRate, to_rate => ToRate, interval => RateInterval,
117+
step_interval => StepInterval, step_count => StepCount},
118+
amoc_throttle_controller:change_rate_gradually(Name, Config).
92119

93120
%% @doc Executes a given function `Fn' when it does not exceed the rate for `Name'.
94121
%%

0 commit comments

Comments
 (0)