Poolex (poolex v1.4.1)

View Source

Usage

In the most typical use of Poolex, you only need to start pool of workers as a child of your application.

children = [
  {Poolex,
    pool_id: :worker_pool,
    worker_module: SomeWorker,
    workers_count: 5}
]

Supervisor.start_link(children, strategy: :one_for_one)

Then you can execute any code on the workers with run/3:

Poolex.run(:worker_pool, &(is_pid?(&1)), checkout_timeout: 1_000)
{:ok, true}

For more information see Getting Started

Summary

Types

Any valid GenServer's name. It may be an atom like :some_pool or a tuple {:via, Registry, {MyApp.Registry, "pool"} if you want to use Registry.

Process id of worker.

Functions

Adds some idle workers to existing pool.

Returns a specification to start this module under a supervisor.

Removes some idle workers from existing pool. If the number of workers to remove is greater than the number of idle workers, all idle workers will be removed.

The main function for working with the pool.

Starts a Poolex process without links (outside of a supervision tree).

Starts a Poolex process linked to the current process.

Types

pool_id()

@type pool_id() :: GenServer.name() | pid()

Any valid GenServer's name. It may be an atom like :some_pool or a tuple {:via, Registry, {MyApp.Registry, "pool"} if you want to use Registry.

poolex_option()

@type poolex_option() ::
  {:busy_workers_impl, module()}
  | {:failed_workers_retry_interval, timeout()}
  | {:idle_overflowed_workers_impl, module()}
  | {:idle_workers_impl, module()}
  | {:max_overflow, non_neg_integer()}
  | {:pool_id, pool_id()}
  | {:pool_size_metrics, boolean()}
  | {:waiting_callers_impl, module()}
  | {:worker_args, [any()]}
  | {:worker_module, module()}
  | {:worker_shutdown_delay, timeout()}
  | {:worker_start_fun, atom()}
  | {:workers_count, non_neg_integer()}
OptionDescriptionExampleDefault value
busy_workers_implModule that describes how to work with busy workersSomeBusyWorkersImplPoolex.Workers.Impl.List
failed_workers_retry_intervalInterval in milliseconds between retry attempts for failed workers5_0001_000
idle_workers_implModule that describes how to work with idle workersSomeIdleWorkersImplPoolex.Workers.Impl.List
idle_overflowed_workers_implModule that describes how to work with idle overflowed workersSomeIdleOverflowedWorkersImplPoolex.Workers.Impl.List
max_overflowHow many workers can be created over the limit20
worker_shutdown_delayDelay (ms) before shutting down overflow worker after release50000
pool_idIdentifier by which you will access the pool:my_poolworker_module value
pool_size_metricsWhether to dispatch pool size metricstruefalse
waiting_callers_implModule that describes how to work with callers queueWaitingCallersImplPoolex.Callers.Impl.ErlangQueue
worker_argsList of arguments passed to the start function[:gg, "wp"][]
worker_moduleName of module that implements our workerMyApp.Workeroption is required
worker_start_funName of the function that starts the worker:run:start_link
workers_countHow many workers should be running in the pool5option is required

run_option()

@type run_option() :: {:checkout_timeout, timeout()}
OptionDescriptionExampleDefault value
checkout_timeoutHow long we can wait for a worker on the call site60_0005000

worker()

@type worker() :: pid()

Process id of worker.

Workers are processes launched in a pool.

Functions

add_idle_workers!(pool_id, workers_count)

@spec add_idle_workers!(pool_id(), pos_integer()) :: :ok | no_return()

Adds some idle workers to existing pool.

child_spec(init_arg)

@spec child_spec([poolex_option()]) :: Supervisor.child_spec()

Returns a specification to start this module under a supervisor.

Options

OptionDescriptionExampleDefault value
busy_workers_implModule that describes how to work with busy workersSomeBusyWorkersImplPoolex.Workers.Impl.List
failed_workers_retry_intervalInterval in milliseconds between retry attempts for failed workers5_0001_000
idle_workers_implModule that describes how to work with idle workersSomeIdleWorkersImplPoolex.Workers.Impl.List
idle_overflowed_workers_implModule that describes how to work with idle overflowed workersSomeIdleOverflowedWorkersImplPoolex.Workers.Impl.List
max_overflowHow many workers can be created over the limit20
worker_shutdown_delayDelay (ms) before shutting down overflow worker after release50000
pool_idIdentifier by which you will access the pool:my_poolworker_module value
pool_size_metricsWhether to dispatch pool size metricstruefalse
waiting_callers_implModule that describes how to work with callers queueWaitingCallersImplPoolex.Callers.Impl.ErlangQueue
worker_argsList of arguments passed to the start function[:gg, "wp"][]
worker_moduleName of module that implements our workerMyApp.Workeroption is required
worker_start_funName of the function that starts the worker:run:start_link
workers_countHow many workers should be running in the pool5option is required

Examples

children = [
  Poolex.child_spec(worker_module: SomeWorker, workers_count: 5),
  # or in another way
  {Poolex, worker_module: SomeOtherWorker, workers_count: 5}
]

Supervisor.start_link(children, strategy: :one_for_one)

remove_idle_workers!(pool_id, workers_count)

@spec remove_idle_workers!(pool_id(), pos_integer()) :: :ok | no_return()

Removes some idle workers from existing pool. If the number of workers to remove is greater than the number of idle workers, all idle workers will be removed.

run(pool_id, fun, options \\ [])

@spec run(pool_id(), (worker :: pid() -> any()), [run_option()]) ::
  {:ok, any()} | {:error, :checkout_timeout}

The main function for working with the pool.

It takes a pool identifier, a function that takes a worker process id as an argument and returns any value. When executed, an attempt is made to find a free worker with specified timeout (5 seconds by default). You can set the timeout using the checkout_timeout option.

Returns:

  • {:ok, result} if the worker was found and the function was executed successfully.
  • {:error, :checkout_timeout} if no free worker was found before the timeout.

Examples

iex> Poolex.start_link(pool_id: :some_pool, worker_module: Agent, worker_args: [fn -> 5 end], workers_count: 1)
iex> Poolex.run(:some_pool, fn pid -> Agent.get(pid, &(&1)) end)
{:ok, 5}

start(opts)

@spec start([poolex_option()]) :: GenServer.on_start()

Starts a Poolex process without links (outside of a supervision tree).

See start_link/1 for more information.

Examples

iex> Poolex.start(pool_id: :my_pool, worker_module: Agent, worker_args: [fn -> 0 end], workers_count: 5)
iex> %Poolex.Private.State{worker_module: worker_module} = :sys.get_state(:my_pool)
iex> worker_module
Agent

start_link(opts)

@spec start_link([poolex_option()]) :: GenServer.on_start()

Starts a Poolex process linked to the current process.

This is often used to start the Poolex as part of a supervision tree.

After the process is started, you can access it using the previously specified pool_id.

Options

OptionDescriptionExampleDefault value
busy_workers_implModule that describes how to work with busy workersSomeBusyWorkersImplPoolex.Workers.Impl.List
failed_workers_retry_intervalInterval in milliseconds between retry attempts for failed workers5_0001_000
idle_workers_implModule that describes how to work with idle workersSomeIdleWorkersImplPoolex.Workers.Impl.List
idle_overflowed_workers_implModule that describes how to work with idle overflowed workersSomeIdleOverflowedWorkersImplPoolex.Workers.Impl.List
max_overflowHow many workers can be created over the limit20
worker_shutdown_delayDelay (ms) before shutting down overflow worker after release50000
pool_idIdentifier by which you will access the pool:my_poolworker_module value
pool_size_metricsWhether to dispatch pool size metricstruefalse
waiting_callers_implModule that describes how to work with callers queueWaitingCallersImplPoolex.Callers.Impl.ErlangQueue
worker_argsList of arguments passed to the start function[:gg, "wp"][]
worker_moduleName of module that implements our workerMyApp.Workeroption is required
worker_start_funName of the function that starts the worker:run:start_link
workers_countHow many workers should be running in the pool5option is required

Examples

iex> Poolex.start_link(pool_id: :other_pool, worker_module: Agent, worker_args: [fn -> 0 end], workers_count: 5)
iex> %Poolex.Private.State{worker_module: worker_module} = :sys.get_state(:other_pool)
iex> worker_module
Agent