8
8
-behaviour (gen_server ).
9
9
10
10
-define (SERVER , ? MODULE ).
11
+ -define (DEFAULT_INTERARRIVAL , 1200 ).
11
12
12
- -required_variable (#{name => interarrival , default_value => 50 ,
13
- verification => {? MODULE , non_neg_integer , 1 },
14
- description => " a delay between creating the processes for two "
15
- " consecutive users (ms, def: 50ms)" ,
16
- update => {? MODULE , maybe_update_interarrival_timer , 2 }}).
13
+ -required_variable (#{name => interarrival , default_value => ? DEFAULT_INTERARRIVAL ,
14
+ verification => {? MODULE , verify_interarrival , 1 },
15
+ description => " Throttle rate for the Scenario:start/1,2 callback (def: 50ms)" ,
16
+ update => {? MODULE , update_interarrival_rate , 2 }}).
17
17
18
18
-record (state , {scenario :: amoc :scenario () | undefined ,
19
19
last_user_id = 0 :: last_user_id (),
20
20
status = idle :: idle | running | terminating | finished |
21
21
{error , any ()} | disabled ,
22
- scenario_state :: any (), % % state returned from Scenario:init/0
23
- create_users = [] :: [amoc_scenario :user_id ()],
24
- tref :: timer :tref () | undefined }).
22
+ scenario_state :: amoc_scenario :state () % % state returned from Scenario:init/0
23
+ }).
25
24
26
25
-type state () :: # state {}.
27
26
% % Internal state of the node's controller
41
40
% % Number of users currently running in the node
42
41
-type last_user_id () :: non_neg_integer ().
43
42
% % Highest user id registered in the node
44
- -type interarrival () :: non_neg_integer ().
43
+ -type interarrival () :: amoc_throttle : rate () | amoc_throttle : throttle ().
45
44
% % Time to wait in between spawning new users
46
45
47
46
% % ------------------------------------------------------------------
65
64
% % ------------------------------------------------------------------
66
65
% % Parameters verification functions
67
66
% % ------------------------------------------------------------------
68
- -export ([maybe_update_interarrival_timer /2 , non_neg_integer /1 ]).
67
+ -export ([update_interarrival_rate /2 , verify_interarrival /1 ]).
69
68
70
- -export ([zero_users_running /0 ]).
69
+ -export ([get_interarrival / 0 , zero_users_running /0 ]).
71
70
72
71
% % ------------------------------------------------------------------
73
72
% % gen_server Function Exports
@@ -122,14 +121,22 @@ disable() ->
122
121
gen_server :call (? SERVER , disable ).
123
122
124
123
% % @private
125
- -spec non_neg_integer (any ()) -> boolean ().
126
- non_neg_integer (Interarrival ) ->
127
- is_integer (Interarrival ) andalso Interarrival >= 0 .
124
+ -spec verify_interarrival (any ()) -> boolean ().
125
+ verify_interarrival (infinity ) ->
126
+ true ;
127
+ verify_interarrival (Rate )
128
+ when is_integer (Rate ), Rate >= 0 ->
129
+ true ;
130
+ verify_interarrival (#{rate := Rate , interval := Interval })
131
+ when is_integer (Rate ), Rate >= 0 , is_integer (Interval ), Interval > 0 ->
132
+ true ;
133
+ verify_interarrival (_ ) ->
134
+ false .
128
135
129
136
% % @private
130
- -spec maybe_update_interarrival_timer (interarrival , term ()) -> ok .
131
- maybe_update_interarrival_timer (interarrival , _ ) ->
132
- gen_server : cast ( ? SERVER , maybe_update_interarrival_timer ).
137
+ -spec update_interarrival_rate (interarrival , amoc_throttle : throttle ()) -> ok .
138
+ update_interarrival_rate (interarrival , #{ rate : = Rate , interval : = Interval } ) ->
139
+ ok = amoc_throttle : change_rate ( interarrival , Rate , Interval ).
133
140
134
141
% % @private
135
142
-spec zero_users_running () -> ok .
@@ -180,8 +187,6 @@ handle_call(_Request, _From, State) ->
180
187
181
188
% % @private
182
189
-spec handle_cast (any (), state ()) -> {noreply , state ()}.
183
- handle_cast (maybe_update_interarrival_timer , State ) ->
184
- {noreply , maybe_update_interarrival_timer (State )};
185
190
handle_cast (zero_users_running , State ) ->
186
191
NewSate = handle_zero_users_running (State ),
187
192
{noreply , NewSate };
@@ -190,12 +195,6 @@ handle_cast(_Msg, State) ->
190
195
191
196
% % @private
192
197
-spec handle_info (any (), state ()) -> {noreply , state ()}.
193
- handle_info (start_user , State ) ->
194
- NewSate = handle_start_user (State ),
195
- {noreply , NewSate };
196
- handle_info (start_all_users , State ) ->
197
- NewSate = handle_start_all_users (State ),
198
- {noreply , NewSate };
199
198
handle_info (_Msg , State ) ->
200
199
{noreply , State }.
201
200
@@ -244,17 +243,14 @@ handle_update_settings(_Settings, #state{status = Status}) ->
244
243
-spec handle_add (amoc_scenario :user_id (), amoc_scenario :user_id (), state ()) ->
245
244
{handle_call_res (), state ()}.
246
245
handle_add (StartId , EndId , # state {last_user_id = LastId ,
247
- create_users = ScheduledUsers ,
248
246
status = running ,
249
247
scenario = Scenario ,
250
- tref = TRef } = State ) when StartId =< EndId ,
248
+ scenario_state = ScenarioState } = State ) when StartId =< EndId ,
251
249
LastId < StartId ->
252
250
amoc_telemetry :execute ([controller , users ], #{count => EndId - StartId + 1 },
253
251
#{scenario => Scenario , type => add }),
254
- NewUsers = lists :seq (StartId , EndId ),
255
- NewScheduledUsers = lists :append (ScheduledUsers , NewUsers ),
256
- NewTRef = maybe_start_timer (TRef ),
257
- {ok , State # state {create_users = NewScheduledUsers , tref = NewTRef , last_user_id = EndId }};
252
+ amoc_users_sup :start_children (Scenario , lists :seq (StartId , EndId ), ScenarioState ),
253
+ {ok , State # state {last_user_id = EndId }};
258
254
handle_add (_StartId , _EndId , # state {status = running } = State ) ->
259
255
{{error , invalid_range }, State };
260
256
handle_add (_StartId , _EndId , # state {status = Status } = State ) ->
@@ -287,23 +283,6 @@ handle_disable(#state{status = idle} = State) ->
287
283
handle_disable (# state {status = Status } = State ) ->
288
284
{{error , {invalid_status , Status }}, State }.
289
285
290
- -spec handle_start_user (state ()) -> state ().
291
- handle_start_user (# state {create_users = [UserId | T ],
292
- scenario = Scenario ,
293
- scenario_state = ScenarioState } = State ) ->
294
- amoc_users_sup :start_child (Scenario , UserId , ScenarioState ),
295
- State # state {create_users = T };
296
- handle_start_user (# state {create_users = [], tref = TRef } = State ) ->
297
- State # state {tref = maybe_stop_timer (TRef )}.
298
-
299
- -spec handle_start_all_users (state ()) -> state ().
300
- handle_start_all_users (# state {create_users = AllUsers ,
301
- scenario = Scenario ,
302
- scenario_state = ScenarioState ,
303
- tref = TRef } = State ) ->
304
- amoc_users_sup :start_children (Scenario , AllUsers , ScenarioState ),
305
- State # state {create_users = [], tref = maybe_stop_timer (TRef )}.
306
-
307
286
% % ------------------------------------------------------------------
308
287
% % helpers
309
288
% % ------------------------------------------------------------------
@@ -316,12 +295,15 @@ start_tables() -> %% ETS creation
316
295
{ok | error , any ()}.
317
296
init_scenario (Scenario , Settings ) ->
318
297
case amoc_config_scenario :parse_scenario_settings (Scenario , Settings ) of
319
- ok -> amoc_scenario :init (Scenario );
298
+ ok ->
299
+ start_interarrival (),
300
+ amoc_scenario :init (Scenario );
320
301
{error , Type , Reason } -> {error , {Type , Reason }}
321
302
end .
322
303
323
304
-spec terminate_scenario (state ()) -> ok | {ok , any ()} | {error , any ()}.
324
305
terminate_scenario (# state {scenario = Scenario , scenario_state = ScenarioState }) ->
306
+ stop_interarrival (),
325
307
amoc_scenario :terminate (Scenario , ScenarioState ).
326
308
327
309
-spec handle_zero_users_running (state ()) -> state ().
@@ -331,35 +313,22 @@ handle_zero_users_running(#state{status = terminating} = State) ->
331
313
handle_zero_users_running (State ) ->
332
314
State .
333
315
334
- -spec maybe_stop_timer (timer :tref () | undefined ) -> undefined .
335
- maybe_stop_timer (undefined ) ->
336
- undefined ;
337
- maybe_stop_timer (TRef ) ->
338
- {ok , cancel } = timer :cancel (TRef ),
339
- undefined .
340
-
341
- -spec get_interarrival () -> interarrival ().
316
+ -spec get_interarrival () -> infinity | interarrival ().
342
317
get_interarrival () ->
343
- amoc_config :get (interarrival ).
344
-
345
- -spec maybe_update_interarrival_timer (state ()) -> state ().
346
- maybe_update_interarrival_timer (# state {tref = undefined } = State ) ->
347
- State ;
348
- maybe_update_interarrival_timer (# state {tref = TRef } = State ) ->
349
- {ok , cancel } = timer :cancel (TRef ),
350
- Value = get_interarrival (),
351
- NewTRef = do_interarrival (Value ),
352
- State # state {tref = NewTRef }.
353
-
354
- -spec maybe_start_timer (timer :tref () | undefined ) -> timer :tref ().
355
- maybe_start_timer (undefined ) ->
356
- Value = get_interarrival (),
357
- do_interarrival (Value );
358
- maybe_start_timer (TRef ) -> TRef .
359
-
360
- do_interarrival (0 ) ->
361
- self () ! start_all_users ,
362
- undefined ;
363
- do_interarrival (Value ) ->
364
- {ok , NewTRef } = timer :send_interval (Value , start_user ),
365
- NewTRef .
318
+ amoc_config :get (interarrival , ? DEFAULT_INTERARRIVAL ).
319
+
320
+ -spec start_interarrival () -> any ().
321
+ start_interarrival () ->
322
+ case get_interarrival () of
323
+ infinity ->
324
+ amoc_throttle :start (interarrival , 1 );
325
+ #{rate := Rate , interval := Interval } ->
326
+ Config = #{rate => Rate , interval => Interval },
327
+ amoc_throttle :start (interarrival , Config );
328
+ Rate ->
329
+ amoc_throttle :start (interarrival , Rate )
330
+ end .
331
+
332
+ -spec stop_interarrival () -> any ().
333
+ stop_interarrival () ->
334
+ amoc_throttle :stop (interarrival ).
0 commit comments