pool_lad v0.0.5 PoolLad
pool_lad
is the younger & more energetic version of :poolboy
.
It's still the lightweight, generic pooling library with focus on simplicity, performance, and rock-solid disaster recovery that we all love...
...but it has just gotten a much needed facelift!
Sample usage
The APIs are almost identical to those of :poolboy
.
Via manual ownership:
iex(1)> {:ok, worker} = PoolLad.borrow(MyWorkerPool)
{:ok, #PID<0.256.0>}
iex(2)> GenServer.call(worker, :get_random_colour)
:blue
iex(3)> PoolLad.return(MyWorkerPool, worker)
:ok
Via transactional ownership:
iex(1)> PoolLad.transaction(
...(1)> MyWorkerPool,
...(1)> fn worker -> GenServer.call(worker, :get_random_colour) end
...(1)> )
:green
Link to this section Summary
Functions
Attempts to "borrow" a worker (pid), or waits until one becomes available.
Returns a specification to start this module under a Supervisor
.
Returns a specification to start this module under a Supervisor
.
Returns the borrowed worker (pid) back to the pool.
Starts a new PoolLad
worker pool.
Both the borrow and the return are facilitated via a single transaction.
Link to this section Functions
borrow(pool, wait? \\ true, timeout \\ 5000)
Specs
Attempts to "borrow" a worker (pid), or waits until one becomes available.
Examples
Get, or wait
If no workers are currently available waits (blocks) until one becomes available,
or until timeout
elapses in which case {:error, :timeout}
will be returned.
Assuming we only have one worker available:
iex(1)> {:ok, pid} = PoolLad.borrow(MyWorkerPool)
{:ok, #PID<0.229.0>}
iex(2)> result = PoolLad.borrow(MyWorkerPool) # will wait (block) for 5 seconds first
{:error, :timeout}
Synchronous get
If no workers are currently available, returns {:error, :full}
immediately.
Assuming we only have one worker available:
iex(1)> {:ok, pid} = PoolLad.borrow(MyWorkerPool, false)
{:ok, #PID<0.229.0>}
iex(2)> result = PoolLad.borrow(MyWorkerPool, false) # will return imediately
{:error, :full}
Custom timeout
You can configure your own timeout
like so:
iex(1)> {:ok, pid} = PoolLad.borrow(MyWorkerPool, true, 2_500)
child_spec(init_arg)
Specs
child_spec({keyword(), keyword()}) :: Supervisor.child_spec()
Returns a specification to start this module under a Supervisor
.
Usage
pool_opts = [name: MyWorkerPool, worker_count: 3, worker_module: MyWorker]
worker_opts = [initial_colours: ~w(red green blue)a]
children = [
{PoolLad, {pool_opts, worker_opts}}
]
Supervisor.start_link(children, strategy: :one_for_one)
Calls child_spec/2
.
child_spec(pool_opts, worker_opts)
Specs
child_spec(keyword(), keyword()) :: Supervisor.child_spec()
Returns a specification to start this module under a Supervisor
.
Usage
pool_opts = [name: MyWorkerPool, worker_count: 3, worker_module: MyWorker]
worker_opts = [initial_colours: ~w(red green blue)a]
children = [
PoolLad.child_spec(pool_opts, worker_opts)
]
Supervisor.start_link(children, strategy: :one_for_one)
return(pool, pid)
Specs
Returns the borrowed worker (pid) back to the pool.
Examples
iex(1)> {:ok, pid} = PoolLad.borrow(MyWorkerPool)
{:ok, #PID<0.229.0>}
iex(2)> PoolLad.return(MyWorkerPool, pid)
:ok
⚠️ If the worker died while on loan and a return was attempted, the return will be accepted but ignored and a warning will be logged.
⚠️ If the return was attempted more than once, the return will be accepted but ignored and a warning will be logged.
start_link(pool_opts, worker_opts)
Specs
start_link(keyword(), keyword()) :: GenServer.on_start()
Starts a new PoolLad
worker pool.
Needs to be supplied pool_opts
and worker_opts
.
Pool options;
:name
(required): unique name, used to interact with the pool:worker_count
(required): the number of workers to be started and supervised:worker_module
(required): the module to be used as a worker, must implementchild_spec/1
Worker options; passed as the init_arg
when starting worker_module
.
Supervision
See child_spec/1
, child_spec/2
.
transaction(pool, function, timeout \\ 5000)
Specs
Both the borrow and the return are facilitated via a single transaction.
Should function
raise, a safe return of the worker to the pool is guaranteed.
iex(1)> PoolLad.transaction(
...(1)> MyWorkerPool,
...(1)> fn worker -> GenServer.call(worker, :get_random_colour) end
...(1)> )
:green