View Source WeightedRoundRobin (WeightedRoundRobin v0.1.2)

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 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.

Link to this section Summary

Functions

Returns a specification to start this module under a supervisor.

Delete a new pool from the generator.

Starts the weighted round-robin generator.

Take elements from the pool in a round-robin fashion.

Link to this section Types

Specs

key() :: any()

Specs

key_weights() :: [{key(), weight()}]

Specs

pool_name() :: any()

Specs

precision() :: non_neg_integer()

Specs

start_option() :: {:name, generator_name :: atom()}

Specs

weight() :: float()

Specs

wrr() :: atom()

Link to this section Functions

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

delete_pool(wrr \\ __MODULE__, pool_name)

View Source

Specs

delete_pool(wrr(), pool_name()) :: :ok

Delete a new pool from the generator.

It is not safe to call this function while serving other processes using take/2.

Link to this function

new_pool(wrr \\ __MODULE__, pool_name, key_weights, precision \\ 100)

View Source

Specs

new_pool(wrr(), pool_name(), key_weights(), precision()) :: :ok

Create a new pool under the generator.

It is safe to reconfigure pools by calling new_pool/4 with different parameters, while take/2 is being served at other processes.

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
Link to this function

take(wrr \\ __MODULE__, pool_name)

View Source

Specs

take(wrr(), pool_name()) :: any()

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: 768, b: 1543, c: 7689} = Enum.frequencies(dist)