README.md

![Elixir CI](https://github.com/hqoss/pool_lad/workflows/Elixir%20CI/badge.svg)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/4cfbf336d5914e09971c015bd68426a0)](https://www.codacy.com/gh/hqoss/pool_lad?utm_source=github.com&utm_medium=referral&utm_content=hqoss/pool_lad&utm_campaign=Badge_Grade)
[![Hex.pm](https://img.shields.io/hexpm/v/pool_lad.svg)](https://hex.pm/packages/pool_lad)
[![Coverage Status](https://coveralls.io/repos/github/hqoss/pool_lad/badge.svg?branch=master)](https://coveralls.io/github/hqoss/pool_lad?branch=master)

# 🙅‍♂️ PoolLad

`pool_lad` is the younger & more energetic version of [`poolboy`](https://github.com/devinus/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!

## Table of contents

-   [Installation](#installation)

-   [API Documentation](#api-documentation)

-   [Sample usage](#sample-usage)

-   [Example application](#example-application)

    -   [Define a worker server](#define-a-worker-server)
    -   [Start the pool](#start-the-pool)
    -   [Do the work](#do-the-work)

-   [`pool_lad` over `poolboy`](#pool_lad-over-poolboy)

-   [TODO](#todo)

## Installation

Add `:pool_lad` as a dependency to your project's `mix.exs`:

```elixir
defp deps do
  [
    {:pool_lad, "~> 0.0.5"}
  ]
end
```

## API Documentation

The full documentation is [published on hex](https://hexdocs.pm/pool_lad/).

## Sample usage

The APIs are almost identical to those of [`:poolboy`](https://github.com/devinus/poolboy).

Via manual ownership:

```elixir
iex(1)> {:ok, pid} = PoolLad.borrow(MyWorkerPool)
{:ok, #PID<0.229.0>}
iex(2)> GenServer.call(pid, :get_latest_count)
{:ok, 42}
iex(3)> PoolLad.return(MyWorkerPool, pid)
:ok
```

Via transactional ownership:

```elixir
iex(1)> PoolLad.transaction(
  MyWorkerPool,
  fn pid -> GenServer.call(pid, :get_latest_count) end
)
{:ok, 42}
```

## Example application

### Define a worker server

```elixir
defmodule MyWorker do
  @moduledoc false

  use GenServer

  @this_module __MODULE__

  def start_link(opts), do: GenServer.start_link(@this_module, opts)

  @impl true
  def init(opts) do
    initial_colours = Keyword.get(opts, :initial_colours, [])
    {:ok, initial_colours}
  end

  @impl true
  def handle_call(:get_random_colour, _from, colours) do
    colour = Enum.random(colours)
    {:reply, colour, colours}
  end
end
```

### Start the pool

```elixir
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)
]

opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
```

### Do the work

Via manual ownership:

```elixir
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:

```elixir
iex(1)> PoolLad.transaction(
...(1)>   MyWorkerPool,
...(1)>   fn worker -> GenServer.call(worker, :get_random_colour) end
...(1)> )
:green
```

## `pool_lad` over `poolboy`

-   Elixir-first
-   Modern APIs, e.g. `DynamicSupervisor`
-   Less code, less pesky logs, less noise
-   More documentation
-   Same performance
-   Maintained
-   0 dependencies

## TODO

A quick and dirty tech-debt tracker, used in conjunction with Issues.

-   [ ] Add overflow functionality
-   [ ] Beautify PoolLad over :poolboy section