Database connection pool management for GoodJob.
This module provides utilities for configuring and managing database connection pools for different GoodJob components:
- Job processing (schedulers, executors)
- LISTEN/NOTIFY (notifier)
- Utility operations (cleanup, stats)
Connection Pool Sizing
GoodJob requires database connections for:
- Job Processing: 1 connection per scheduler process (max_processes)
- LISTEN/NOTIFY: 1 dedicated connection (separate from pool)
- Utility Operations: Shared with job processing pool
Recommended Pool Sizes
For External Mode (separate worker process):
# config/prod.exs
config :my_app, MyApp.Repo,
pool_size: GoodJob.Config.max_processes() + 2 # +2 for utility operations (cleanup, etc.)For Async Mode (same process as web server):
# config/dev.exs
config :my_app, MyApp.Repo,
pool_size: web_server_processes + GoodJob.Config.max_processes() + 2Statement and Lock Timeouts
GoodJob can configure PostgreSQL timeouts to prevent long-running queries from blocking other operations:
# config/prod.exs
config :good_job,
database_statement_timeout: 30_000, # 30 seconds
database_lock_timeout: 5_000 # 5 secondsThese timeouts are set per-connection when the pool is initialized.
Summary
Functions
Applies database configuration (timeouts, pool size) to a repository.
Calculates recommended pool size based on GoodJob configuration.
Returns SQL commands to set timeouts (for use in after_connect).
Calculates total connections needed (including LISTEN/NOTIFY).
Types
@type postgrex_conn() :: %{__struct__: atom()}
Functions
@spec configure_repo(Ecto.Repo.t()) :: {:ok, keyword()}
Applies database configuration (timeouts, pool size) to a repository.
This should be called during application startup to ensure all connections in the pool have the correct settings.
@spec recommended_pool_size() :: integer()
Calculates recommended pool size based on GoodJob configuration.
Returns the recommended pool size for the main repository.
@spec set_timeouts(postgrex_conn()) :: :ok
Returns SQL commands to set timeouts (for use in after_connect).
Use this in your Repo configuration:
config :my_app, MyApp.Repo,
after_connect: {GoodJob.RepoPool, :set_timeouts}Or manually:
defmodule MyApp.Repo do
def init(_type, config) do
config = Keyword.put(config, :after_connect, fn conn ->
GoodJob.RepoPool.set_timeouts(conn)
end)
{:ok, config}
end
end
@spec total_connections_needed() :: integer()
Calculates total connections needed (including LISTEN/NOTIFY).
This includes:
- Job processing pool
- LISTEN/NOTIFY connection (separate)
- Utility operations (shared with job processing)