View Source amoc_throttle (amoc v4.0.0)

Allows limiting the number of users' actions per interval.

Summary

Types

Configuration throttle for a gradual rate change.

Gradual plan details. Must specify a gradual/0, and a plan/0.

Time in milliseconds between two events.

In milliseconds, defaults to 60000 (one minute).

Atom representing the name of the throttle.

Configuration plan for a gradual rate change.

Number of events per given interval/0.

t/0

Throttle unit of measurement

Functions

Sets the throttle Config for Name according to the given values.

Allows to set a plan of gradual rate changes for a given Name.

Pauses executions for the given Name as if Rate was set to 0.

Resumes the executions for the given Name, to their original configuration value.

Executes a given function Fn when it does not exceed the rate for Name.

Sends a given message to erlang:self()

Sends a given message Msg to a given Pid when the rate for Name allows for that.

Starts the throttle mechanism for a given Name with a given config.

Stops the throttle mechanism for the given Name.

Unlocks executions for the given Name by setting Rate to infinity.

Blocks the caller until the throttle mechanism allows.

Types

-type gradual() ::
          #{from_rate := non_neg_integer(), to_rate := non_neg_integer(), interval => interval()} |
          #{from_interarrival := non_neg_integer(), to_interarrival := non_neg_integer()}.

Configuration throttle for a gradual rate change.

"from" and "to" prefixed parameters, whether rates or interarrivals, are required. interval applies only to rate and defaults to 1s.

-type gradual_plan() :: #{throttle := gradual(), plan := plan()}.

Gradual plan details. Must specify a gradual/0, and a plan/0.

-type interarrival() :: infinity | non_neg_integer().

Time in milliseconds between two events.

It can also be:

  • infinity for effectively pausing the throttle,
  • zero for effectively unlocking all throttling.
-type interval() :: non_neg_integer().

In milliseconds, defaults to 60000 (one minute).

Note that an interval of zero means effectively allowing rate/0 number of executions in parallel. It might be expected for this to be always infinity as a result of the limit when dividing by zero, but this needs to be made explicit in the rate/0 by setting it to infinity.

-type name() :: atom().

Atom representing the name of the throttle.

-type plan() ::
          #{step_interval := pos_integer(), step_count := pos_integer()} | #{duration := pos_integer()}.

Configuration plan for a gradual rate change.

The throttle mechanism will take a series of discrete steps, for as long as the duration given, or in the shape of the step_interval and step_count.

-type rate() :: infinity | non_neg_integer().

Number of events per given interval/0.

It can also be:

  • infinity for effectively unlocking all throttling,
  • zero for effectively pausing the throttle.
-type t() :: #{rate := rate(), interval => interval()} | #{interarrival := interarrival()}.

Throttle unit of measurement

Functions

Link to this function

change_rate(Name, Config)

View Source
-spec change_rate(name(), t() | rate()) -> ok | {error, any()}.

Sets the throttle Config for Name according to the given values.

Link to this function

change_rate_gradually(Name, Config)

View Source
-spec change_rate_gradually(name(), gradual_plan()) -> ok | {error, any()}.

Allows to set a plan of gradual rate changes for a given Name.

The configuration will be changed in a series of consecutive steps. Rates can be changed upwards as well as downwards. See the documentation for gradual_plan/0 for more info.

Be aware that, at first, the rate will be changed to the initial point given in the configuration, and this is not considered a step.

-spec pause(name()) -> ok | {error, any()}.

Pauses executions for the given Name as if Rate was set to 0.

Does not stop the scheduled rate changes. resume/1 undoes the pausing.

-spec resume(name()) -> ok | {error, any()}.

Resumes the executions for the given Name, to their original configuration value.

It is the counterpart to the pause/1 API, resuming the execution of what that mechanism paused.

-spec run(name(), fun(() -> any())) -> ok | {error, any()}.

Executes a given function Fn when it does not exceed the rate for Name.

Fn is executed in the context of a new process spawned on the same node on which the process executing run/2 runs, so a call to run/2 is non-blocking.

Diagram showing function execution flow in distributed environment.

  title Amoc distributed
  participantgroup  **Slave node**
      participant User
      participant Async runner
  end
  participantgroup **Master node**
      participant Throttle process
  end
  box left of User: request telemetry event
 
  User -> *Async runner : Fun
 
  User -> Throttle process : {schedule, Async runner PID}
  box right of Throttle process : request telemetry event
 
  ==throtlling delay==
 
  Throttle process -> Async runner: scheduled
  box right of Throttle process : execution telemetry event
  space -5
  box left of Async runner : execution telemetry event
  abox over Async runner : scheduled action
  activate Async runner
  space
  deactivate Async runner
  Async runner ->Throttle process:'DOWN'
  destroy Async runner
-spec send(name(), any()) -> ok | {error, any()}.

Sends a given message to erlang:self()

See also: send/3.

-spec send(name(), pid(), any()) -> ok | {error, any()}.

Sends a given message Msg to a given Pid when the rate for Name allows for that.

May be used to schedule tasks.

-spec start(name(), t() | rate()) -> {ok, started | already_started} | {error, any()}.

Starts the throttle mechanism for a given Name with a given config.

Name is needed to identify the rate as a single test can have different rates for different tasks.

-spec stop(name()) -> ok | {error, any()}.

Stops the throttle mechanism for the given Name.

-spec unlock(name()) -> ok | {error, any()}.

Unlocks executions for the given Name by setting Rate to infinity.

-spec wait(name()) -> ok | {error, any()}.

Blocks the caller until the throttle mechanism allows.