View Source WeightedRoundRobin (WeightedRoundRobin v0.1.8)
A local, decentralized and scalable weighted round-robin generator.
It allows developers to generate a sequence, evenly distributed, attending a
predefined set of weights attributed to elements of any type. The take/2
function is guaranteed to be atomic and isolated.
Generators can have any number of pools, each under a different pool_name
.
The precision
indicates how many precision digits you want at the generator
output (so 100 indicates you want a two digits precision).
The application can have multiple instances of the generator, but in this
case every function needs to be prefixed with the generator name, indicated
as wrr
.
Internally the pools are versioned using an ETS table for each version of the
pool created with new_pool
. Accesses hit the newer version first, and
migrate from the older version to the newer version along the time. When a
new generation is started, the oldest one is deleted by an internal GC.
Link to this section Summary
Functions
Returns a specification to start this module under a supervisor.
Delete a new pool from the generator.
Executes the garbage collector.
Create a new pool under the generator.
Resets the wrr state.
Starts the weighted round-robin generator.
Take elements from the pool in a round-robin fashion.
Link to this section Types
Link to this section Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
Specs
Delete a new pool from the generator.
It is not safe to call this function while serving other processes using
take
or concurrently with new_pool
for the same pool.
Executes the garbage collector.
Used when the automatic GC is disabled by passing :gc_interval
as
:infinity
to start_link
.
Specs
new_pool(pool_name(), key_weights()) :: :ok
Create a new pool under the generator.
It is safe to reconfigure pools by calling new_pool
with different
parameters, while take
is being served at other processes.
Keys with weight equal to 0.0 will be filtered out.
Specs
new_pool(pool_name(), key_weights(), [option()]) :: :ok
Specs
new_pool(wrr(), pool_name(), key_weights(), [option()]) :: :ok
Specs
reset(wrr()) :: :ok
Resets the wrr state.
This drops all previously configured pools and resets version counter.
It is not safe to call this function while serving other processes using
take
or concurrently with new_pool
for the same pool.
Specs
start_link([start_option()]) :: {:ok, pid()} | {:error, term()}
Starts the weighted round-robin generator.
You typically don't need to start the weighted round-robin generator, one is started automatically at application start, except if you explicitly say to not start one at your config:
config :wrr, start: false
So, manually it can be started as:
WeightedRoundRobin.start_link(name: MyApp.WeightedRoundRobin)
In your supervisor tree, you would write:
Supervisor.start_link([
{WeightedRoundRobin, name: MyApp.WeightedRoundRobin}
], strategy: :one_for_one)
options
Options
The weighted round-robin generator requires the following key:
:name
- the name of the generator and its tables:gc_interval
- If it is set, an integer > 0 is expected defining the interval time in milliseconds to garbage collection to run, deleting the older versions. If this option is not set, garbage collection is executed every 1 minute. If set to :infinity, garbage collection is never executed automatically andgc
will need to be executed explicitly.:gc_cleanup_min_timeout
- An integer > 0 defining the min timeout in milliseconds for triggering the next cleanup.
Specs
Take elements from the pool in a round-robin fashion.
examples
Examples
iex> :ok = WeightedRoundRobin.new_pool(:pool, [a: 0.1, b: 0.2, c: 1.0])
iex> dist = Enum.map(1..10_000, fn _ -> WeightedRoundRobin.take(:pool) end)
iex> %{a: 775, b: 1537, c: 7688} = Enum.frequencies(dist)