Handler.Pool (handler v0.2.0) View Source

Manage a pool of resources used to run dangerous functions

The Pool provides both a synchrous interface (run/3) as well as an asynchronous interface (async/3 and await/1) for running functions.

Composing Pools

This module also provides a way to have limited resources for particular use-cases, that end up sharing bigger pools of resources. Take for instance a hosted multi-tenant application where you can safely use up to 10GB of memory for a particular task, but you don't want any one customer to use the whole pool, so each customer has a limit of just 5GB. You can handle this scenario using the delegate_to configuration.

{:ok, _pid} = Handler.Pool.start_link(%Handler.Pool{
  max_memory: 10 * 1024 * 1024 * 1024,
  name: :shared_pool
})
{:ok, _pid} = Handler.Pool.start_link(%Handler.Pool{
  delegate_to: :shared_pool,
  max_memory: 5 * 1024 * 1024 * 1024,
  name: :customer_pool
})

100 = Pool.run(:customer_pool, fn -> 10 * 10 end, max_heap_bytes: 100 * 1024)

Link to this section Summary

Functions

Asynchronously start a job

Returns a specification to start this module under a supervisor.

Run a potentially dangerous function in the pool

Link to this section Types

Specs

Specs

name() :: GenServer.name()

Specs

pool() :: GenServer.server()

Specs

t() :: %Handler.Pool{
  delegate_to: nil | name(),
  max_memory_bytes: non_neg_integer(),
  max_workers: non_neg_integer(),
  name: nil | name()
}

Link to this section Functions

Specs

async(pool(), (() -> any()), Handler.opts()) ::
  {:ok, reference()} | {:reject, exception()}

Asynchronously start a job

Take a potentially dangerous function and run it in the pool. You'll either get back an ok tuple with a reference you can pass to the await/1 function, or a reject tuple with an exception describing why the function couldn't be started.

Specs

await(reference()) :: any() | {:error, Handler.exception()}

Returns a specification to start this module under a supervisor.

See Supervisor.

Specs

run(pool(), (() -> any()), Handler.opts()) ::
  any() | {:error, Handler.exception()} | {:reject, exception()}

Run a potentially dangerous function in the pool

This function has pretty much the same interface as Handler.run/2 with the addition of the {:reject, t:exception()} return values when the pool does not have enough resources to start a particular function.