Foundation.Infrastructure.ConnectionManager (foundation v0.1.0)

Connection pooling manager wrapping Poolboy for resource management.

Provides a unified interface for managing connection pools across different resource types (database connections, HTTP clients, etc.) with proper lifecycle management and telemetry integration.

Usage

# Start a pool for database connections
{:ok, pool_pid} = ConnectionManager.start_pool(:database, [
  size: 10,
  max_overflow: 5,
  worker_module: MyApp.DatabaseWorker,
  worker_args: [host: "localhost", port: 5432]
])

# Execute work with a pooled connection
result = ConnectionManager.with_connection(:database, fn worker ->
  GenServer.call(worker, {:query, "SELECT * FROM users"})
end)

# Get pool status
status = ConnectionManager.get_pool_status(:database)

Pool Configuration

  • :size - Initial pool size (default: 5)
  • :max_overflow - Maximum additional workers (default: 10)
  • :worker_module - Module implementing the worker behavior
  • :worker_args - Arguments passed to worker start_link/1
  • :strategy - Pool strategy (default: :lifo)

Telemetry Events

  • [:foundation, :foundation, :connection_pool, :checkout] - Connection checked out
  • [:foundation, :foundation, :connection_pool, :checkin] - Connection returned
  • [:foundation, :foundation, :connection_pool, :timeout] - Checkout timeout
  • [:foundation, :foundation, :connection_pool, :overflow] - Pool overflow occurred

Summary

Functions

Returns a specification to start this module under a supervisor.

Gets the current status of a connection pool.

Lists all active connection pools.

Starts the ConnectionManager GenServer.

Starts a new connection pool with the given configuration.

Stops an existing connection pool.

Executes a function with a connection from the specified pool.

Types

pool_config()

@type pool_config() :: [
  size: non_neg_integer(),
  max_overflow: non_neg_integer(),
  worker_module: module(),
  worker_args: term(),
  strategy: :lifo | :fifo
]

pool_name()

@type pool_name() :: atom()

pool_status()

@type pool_status() :: %{
  size: non_neg_integer(),
  overflow: non_neg_integer(),
  workers: non_neg_integer(),
  waiting: non_neg_integer(),
  monitors: non_neg_integer()
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_pool_status(pool_name)

@spec get_pool_status(pool_name()) :: {:ok, pool_status()} | {:error, :not_found}

Gets the current status of a connection pool.

Parameters

  • pool_name - Pool to get status for

Returns

  • {:ok, status} - Pool status information
  • {:error, :not_found} - Pool doesn't exist

list_pools()

@spec list_pools() :: [pool_name()]

Lists all active connection pools.

Returns

  • [pool_name] - List of active pool names

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the ConnectionManager GenServer.

start_pool(pool_name, config)

@spec start_pool(pool_name(), pool_config()) :: {:ok, pid()} | {:error, term()}

Starts a new connection pool with the given configuration.

Parameters

  • pool_name - Unique identifier for the pool
  • config - Pool configuration options

Returns

  • {:ok, pid} - Pool started successfully
  • {:error, reason} - Pool failed to start

stop_pool(pool_name)

@spec stop_pool(pool_name()) :: :ok | {:error, :not_found}

Stops an existing connection pool.

Parameters

  • pool_name - Pool identifier to stop

Returns

  • :ok - Pool stopped successfully
  • {:error, :not_found} - Pool doesn't exist

with_connection(pool_name, fun, timeout \\ 5000)

@spec with_connection(pool_name(), (pid() -> term()), timeout()) ::
  {:ok, term()} | {:error, term()}

Executes a function with a connection from the specified pool.

Automatically handles checkout/checkin and provides proper error handling with telemetry integration.

Parameters

  • pool_name - Pool to get connection from
  • fun - Function to execute with the worker
  • timeout - Checkout timeout (default: 5000ms)

Returns

  • {:ok, result} - Function executed successfully
  • {:error, reason} - Execution failed or pool unavailable