Skip to content

Commit 83eb6c1

Browse files
author
Denys Gonchar
committed
fixing crashes at throttle_SUITE
1 parent 06bb385 commit 83eb6c1

2 files changed

Lines changed: 68 additions & 58 deletions

File tree

src/throttle/amoc_throttle_controller.erl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -256,26 +256,30 @@ do_gradual_change_rate(
256256

257257
-spec continue_plan(name(), state(), throttle_info(), change_rate_plan()) -> state().
258258
continue_plan(Name, State, Info, #change_rate_plan{rates = [Rate]} = Plan) ->
259-
Interval = Info#throttle_info.interval,
260-
TRef = Plan#change_rate_plan.timer,
261-
Info1 = do_change_rate(Name, Rate, Interval, Info),
262-
{ok, cancel} = timer:cancel(TRef),
263-
consume_all_timer_ticks({change_plan, Name}),
259+
Info1 = do_change_rate(Name, Rate, Info#throttle_info.interval, Info),
260+
stop_change_plan(Name, Plan),
264261
State#{Name => Info1#throttle_info{change_plan = undefined}};
265262
continue_plan(Name, State, Info, #change_rate_plan{rates = [Rate | Rates]} = Plan) ->
266263
Info1 = do_change_rate(Name, Rate, Info#throttle_info.interval, Info),
267264
NewPlan = Plan#change_rate_plan{rates = Rates},
268265
State#{Name => Info1#throttle_info{change_plan = NewPlan}}.
269266

267+
-spec stop_change_plan(name(), undefined | change_rate_plan()) -> ok.
268+
stop_change_plan(_Name, undefined) -> ok;
269+
stop_change_plan(Name, #change_rate_plan{timer = TRef}) ->
270+
{ok, cancel} = timer:cancel(TRef),
271+
consume_all_timer_ticks({change_plan, Name}).
272+
270273
-spec consume_all_timer_ticks(any()) -> ok.
271274
consume_all_timer_ticks(Msg) ->
272275
receive
273276
Msg -> consume_all_timer_ticks(Msg)
274277
after 0 -> ok
275278
end.
276279

277-
do_run_op(stop, Name, #throttle_info{pool_sup = PoolSup}, State) ->
280+
do_run_op(stop, Name, #throttle_info{pool_sup = PoolSup, change_plan = ChangePlan}, State) ->
278281
ok = amoc_throttle_pooler:stop_pool(PoolSup),
282+
stop_change_plan(Name, ChangePlan),
279283
{reply, ok, maps:remove(Name, State)};
280284
do_run_op(pause, Name, #throttle_info{pool_config = PoolConfig, active = true} = Info, State) ->
281285
Fun = fun(_, #{pid := Pid}) ->

test/throttle_SUITE.erl

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,70 @@
66
-compile([export_all, nowarn_export_all]).
77

88
-define(DEFAULT_INTERVAL, 60000). %% one minute
9-
-define(RECV(Msg, Timeout), receive Msg -> ok after Timeout -> {error, not_received_yet} end).
9+
-define(RECV(Msg, Timeout), receive Msg -> ok after (Timeout + 50) -> {error, not_received_yet} end).
1010

1111
all() ->
1212
[
13-
{group, api},
14-
{group, properties}
13+
{group, properties},
14+
{group, api}
1515
].
1616

1717
groups() ->
1818
[
19-
{api, [parallel],
20-
[
21-
start,
22-
start_descriptive,
23-
start_interarrival,
24-
start_interarrival_zero,
25-
start_interarrival_infinity,
26-
start_rate_zero,
27-
start_rate_infinity,
28-
start_interval_zero,
29-
low_rate_does_not_get_remapped,
30-
low_interval_does_not_get_remapped,
31-
start_and_stop,
32-
change_rate,
33-
interval_equal_zero_limits_parallelism,
34-
change_rate_to_interval_zero_limits_parallelism,
35-
change_rate_triggers_parallelism,
36-
change_rate_gradually,
37-
change_interarrival_gradually,
38-
change_rate_gradually_verify_descriptions,
39-
just_wait,
40-
wait_for_process_to_die_sends_a_kill,
41-
async_runner_dies_while_waiting_raises_exit,
42-
async_runner_dies_when_throttler_dies,
43-
pause_and_resume,
44-
get_state
45-
]},
46-
{properties, [],
47-
[
48-
change_rate_gradually_verify_descriptions_properties,
49-
% Note that the smallest delay possible for a process is 1ms (receive operations),
50-
% hence if we give for example 10 workers 1ms delays, we get 600_000 ticks per minute.
51-
% and if we give for example 48 workers 1ms delays, we get 2_880_000 ticks per minute.
52-
% That means, that is realistically the maximum rate we could possibly manage
53-
% with a static pool of such number of workers.
54-
pool_config_is_precise_for_rates_1,
55-
pool_config_is_precise_for_rates_2,
56-
pool_config_is_precise_for_rates_3,
57-
pool_config_is_precise_for_rates_4,
58-
pool_config_is_precise_for_rates_5,
59-
pool_config_is_precise_for_rates_6,
60-
pool_config_is_precise_for_rates_7,
61-
pool_config_is_precise_for_rates_8,
62-
pool_config_is_precise_for_rates_9,
63-
pool_config_is_precise_for_rates_10
64-
]}
19+
{api, [parallel, {repeat, 3}], api_testcases()},
20+
{properties, [], properties_testcases()}
21+
].
22+
23+
api_testcases() ->
24+
[
25+
start,
26+
start_descriptive,
27+
start_interarrival,
28+
start_interarrival_zero,
29+
start_interarrival_infinity,
30+
start_rate_zero,
31+
start_rate_infinity,
32+
start_interval_zero,
33+
low_rate_does_not_get_remapped,
34+
low_interval_does_not_get_remapped,
35+
start_and_stop,
36+
change_rate,
37+
interval_equal_zero_limits_parallelism,
38+
change_rate_to_interval_zero_limits_parallelism,
39+
change_rate_triggers_parallelism,
40+
change_rate_gradually,
41+
change_interarrival_gradually,
42+
change_rate_gradually_verify_descriptions,
43+
just_wait,
44+
wait_for_process_to_die_sends_a_kill,
45+
async_runner_dies_while_waiting_raises_exit,
46+
async_runner_dies_when_throttler_dies,
47+
pause_and_resume,
48+
get_state
49+
].
50+
51+
properties_testcases() ->
52+
[
53+
change_rate_gradually_verify_descriptions_properties,
54+
% Note that the smallest delay possible for a process is 1ms (receive operations),
55+
% hence if we give for example 10 workers 1ms delays, we get 600_000 ticks per minute.
56+
% and if we give for example 48 workers 1ms delays, we get 2_880_000 ticks per minute.
57+
% That means, that is realistically the maximum rate we could possibly manage
58+
% with a static pool of such number of workers.
59+
pool_config_is_precise_for_rates_1,
60+
pool_config_is_precise_for_rates_2,
61+
pool_config_is_precise_for_rates_3,
62+
pool_config_is_precise_for_rates_4,
63+
pool_config_is_precise_for_rates_5,
64+
pool_config_is_precise_for_rates_6,
65+
pool_config_is_precise_for_rates_7,
66+
pool_config_is_precise_for_rates_8,
67+
pool_config_is_precise_for_rates_9,
68+
pool_config_is_precise_for_rates_10
6569
].
6670

6771
init_per_suite(Config) ->
72+
meck:new(amoc_throttle_config, [passthrough, non_strict, no_link]),
6873
application:ensure_all_started(amoc),
6974
amoc_cluster:set_master_node(node()),
7075
TelemetryEvents = [[amoc, throttle, Event] || Event <- [init, rate, request, execute, process]],
@@ -74,18 +79,19 @@ init_per_suite(Config) ->
7479
end_per_suite(_) ->
7580
application:stop(amoc),
7681
telemetry_helpers:stop(),
82+
meck:unload(),
7783
ok.
7884

7985
init_per_group(properties, Config) ->
80-
meck:new(amoc_throttle_config, [passthrough, non_strict, no_link]),
81-
meck:expect(amoc_throttle_config, no_of_processes, [], 100),
86+
ok = meck:expect(amoc_throttle_config, no_of_processes, [], 100),
8287
Config;
8388
init_per_group(_, Config) ->
8489
Config.
8590

8691
end_per_group(properties, _Config) ->
87-
meck:unload(amoc_throttle_config);
92+
ok = meck:delete(amoc_throttle_config, no_of_processes, 0);
8893
end_per_group(_, _Config) ->
94+
[amoc_throttle:stop(TC) || TC <- api_testcases() -- [async_runner_dies_when_throttler_dies]],
8995
ok.
9096

9197
init_per_testcase(_, Config) ->

0 commit comments

Comments
 (0)