GenPool

WIP

A pooled process with the option to centralize state, decouple the message queue and handle backpressure using sbroker.

The goal is to:

Example

defmodule ExampleGenPool do
  use GenPool,
    pool_size: 5,
    shared_state?: true,
    external_broker?: false,
    broker: GenPool.DefaultBroker,
    backend: %GenPool.Backend.Ane{}

  defmodule State do
    defstruct count: 0
  end

  @impl true
  def init(_) do
    {:ok, %State{count: 0}}
  end

  @impl true
  def handle_call({:add, value}, _from, state) do
    {:reply, state.count + value, %State{state | count: state.count + value}}
  end

  @impl true
  def handle_cast({:add, value}, state) do
    {:noreply, %State{state | count: state.count + value}}
  end

  def start_link(opts \\ []) do
    GenPool.start_link(__MODULE__, opts, [])
  end

  def add(value) do
    GenPool.call(__MODULE__, {:add, value})
  end

  def add_casting(value) do
    GenPool.cast(__MODULE__, {:add, value})
  end
end

Optionally you can define your own broker with:

defmodule MyGenPoolBroker do
  use GenPool.Broker

  @impl true
  def process_queue do
    [
      queue_type: :filo,
      timeout: :infinity
    ]
  end

  @impl true
  def client_queue do
    [
      queue_type: :fifo,
      timeout: 10_000, # call timeout
      min: 0,

      # max value for backpressure
      # if the message queue reaches this value
      # it will throw {:error, :too_many_requests} on casts and calls
      max: :infinity
    ]
  end
end

Running in iex:

iex(1)> ExampleGenPool.start_link()
iex(2)> ExampleGenPool.add(5)
5
iex(3)> ExampleGenPool.add_casting(5)
:ok
iex(4)> ExampleGenPool.add(5)
15

Installation

This package can be installed by adding gen_pool to your list of dependencies in mix.exs:

def deps do
  [
    {:gen_pool, "~> 0.0.1"}
  ]
end

Documentation can be found at https://hexdocs.pm/gen_pool.