Chosen.LockManager (chosen v0.1.2)

Copy Markdown

Centralized advisory lock coordination system for Chosen.

Provides a shared PostgreSQL connection pool manager that handles all advisory lock operations, significantly reducing database connection overhead by consolidating N connections (one per Chosen instance) into a single connection per VM.

System Architecture

The LockManager orchestrates:

  • Single persistent Postgrex database connection
  • Lock acquisition and release operations for multiple Chosen instances
  • Automatic process monitoring with lock cleanup on termination
  • Intelligent polling mechanism for lock contention scenarios
  • Centralized observability for distributed lock states

State Persistence

Lock ownership tracking includes process monitoring for automatic cleanup. Queued lock requests are maintained with configurable retry intervals.

Summary

Functions

Returns a specification to start this module under a supervisor.

Queries the database connection health status.

Retrieves all active locks for debugging and monitoring purposes.

Releases a previously acquired advisory lock.

Requests acquisition of an advisory lock (asynchronous operation).

Initializes and starts the LockManager GenServer.

Types

lock_info()

@type lock_info() :: %{owner: pid(), monitor_ref: reference(), name: term()}

lock_key()

@type lock_key() :: {integer(), integer()}

pending_request()

@type pending_request() :: %{
  from: pid(),
  monitor_ref: reference(),
  timer_ref: reference() | nil,
  polling_interval: integer()
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

connection_status(server \\ __MODULE__)

@spec connection_status(GenServer.server()) :: :connected | :disconnected

Queries the database connection health status.

Useful for system health checks and monitoring.

list_locks(server \\ __MODULE__)

@spec list_locks(GenServer.server()) :: %{required(lock_key()) => lock_info()}

Retrieves all active locks for debugging and monitoring purposes.

Returns a mapping from lock keys to their associated lock information.

release_lock(server \\ __MODULE__, name)

@spec release_lock(GenServer.server(), term()) :: :ok

Releases a previously acquired advisory lock.

Pending requests for the same lock are automatically processed in queue order.

request_lock(server \\ __MODULE__, name, polling_interval \\ 300)

@spec request_lock(GenServer.server(), term(), integer()) :: :ok

Requests acquisition of an advisory lock (asynchronous operation).

The requesting process receives a :got_lock message upon successful acquisition. When a lock is contested, requests enter a queue with periodic retry attempts governed by the polling_interval parameter.

Returns :ok immediately - actual lock acquisition happens asynchronously.

start_link(opts \\ [])

Initializes and starts the LockManager GenServer.

Configuration options:

  • :connect_opts - Direct Postgrex connection parameters (optional)
  • :repo - Ecto repository for extracting connection settings (optional)
  • :name - Process registration name (defaults to: MODULE)