Loader (loader v0.2.1)
Loader is a load-generating library that allows you to define arbitrary distributions of arbitrary work via mathematical functions and small structs.
These distributions, called LoadProfiles, can be paired up with a WorkSpec and executed to generate load, and gather statistics from a client's perspective.
example
Example
Let's assume there is some service at http://website.io/public/api, and we want to generate some simple, uniform load against that service.
alias Loader.{LoadProfile, WorkResponse, WorkSpec}
uniform_one_minute_profile =
LoadProfile.new(%{
target_running_time: 60,
function: &LoadProfile.Curves.uniform(&1, 10) # y = 10
})
service_call_spec = %WorkSpec{
task: fn ->
Finch.build(:get, "http://website.io/public/api", [])
|> Finch.request(MyApp.Finch)
end,
is_success?: fn %WorkResponse{data: res} ->
case res do
{:ok, _any} -> true
_any -> false
end
end
}
Loader.execute_profile(uniform_one_minute_profile, service_call_spec)The above example will generate a uniform 10 requests/ second against our imaginary service. We could also write additional load profiles, and run them concurrently to generate constructive interference!
linear_one_minute_profile =
LoadProfile.new(%{
target_running_time: 60,
function: &LoadProfile.Curves.linear(&1, 1.5, 5) # y = 1.5x + 5
})
sine_wave_one_minute_profile =
LoadProfile.new(%{
target_running_time: 60,
function: fn x -> 5 * (:math.sin(x) + 1) end # y = 5 * (sin(x) + 1)
})
Loader.execute_profiles([
{uniform_one_minute_profile, service_call_spec},
{linear_one_minute_profile, service_call_spec},
{sine_wave_one_minute_profile, service_call_spec},
])Visualized, this second example would produce load on the service as shown, where x is in seconds and y is requests/ second:

telemetry
Telemetry
Loader emits the following telemetry events:
[:loader, :load_profile_execution, :start]- emitted whenLoader.execute_profile/2orLoader.execute_profiles/1is called.[:loader, :load_profile_execution, :stop]- emitted when aLoadProfilehas been fully emitted, regardless of the number of successes or failures of individual tasks[:loader, :task, :start]- emitted when the:taskcallback from aLoader.WorkSpecis invoked[:loader, :task, :stop]- emitted when the:taskcallback from aLoader.WorkSpecis invoked[:loader, :task, :exception]- emitted if there is an uncaught exception while invoking the:taskcallback from aLoader.WorkSpec
See the documentation for the Loader.Telemetry module for more information.
installation
Installation
The package can be installed by adding loader to your list of dependencies in mix.exs:
def deps do
[
{:loader, "~> 0.2.0"}
]
endThe docs can be found at https://hexdocs.pm/loader.
Link to this section Summary
Functions
Execute tasks based on the work_spec, scheduled based on the parameters in the load_profile
Execute several LoadProfiles simultaneously, each with their supplied WorkSpec
Link to this section Functions
execute_profile(load_profile, work_spec)
@spec execute_profile(Loader.LoadProfile.t(), Loader.WorkSpec.t()) :: DynamicSupervisor.on_start_child()
Execute tasks based on the work_spec, scheduled based on the parameters in the load_profile
execute_profiles(profile_spec_pairs)
@spec execute_profiles([{Loader.LoadProfile.t(), Loader.WorkSpec.t()}]) :: [ DynamicSupervisor.on_start_child() ]
Execute several LoadProfiles simultaneously, each with their supplied WorkSpec