ExAthena.RequestQueue (ExAthena v0.15.1)

Copy Markdown View Source

ETS-backed GenServer semaphore that limits concurrent in-flight requests per provider.

Each provider has an independent slot cap (see ExAthena.Config.request_queue_max_depth/1). acquire/2 blocks the caller until a slot is available; release/1 frees the slot and wakes the next queued caller (FIFO). depth/1 reads the ETS counter directly, never blocking the caller.

The queue is opt-in and disabled by default. When the GenServer is not running (feature disabled), acquire/1 and release/1 are no-ops returning :ok.

Enable via:

config :ex_athena, :request_queue, enabled: true

Dead-waiter cleanup

Every blocked caller is monitored. If a caller process exits before its slot is granted, the monitor fires and removes the dead entry from the queue so the corresponding slot is correctly freed on the next release/1.

Summary

Functions

Acquire a slot for provider. Blocks the caller until a slot is available or timeout milliseconds elapse (default 5 000 ms).

Cancel any pending acquire for the calling process on provider.

Returns a specification to start this module under a supervisor.

Return the number of active (acquired) slots for provider.

Release a previously acquired slot for provider. Returns :ok.

Functions

acquire(provider, timeout \\ 5000)

@spec acquire(atom(), non_neg_integer()) :: :ok

Acquire a slot for provider. Blocks the caller until a slot is available or timeout milliseconds elapse (default 5 000 ms).

Returns :ok when a slot is granted. When the GenServer is not running (feature disabled), returns :ok immediately as a no-op.

cancel_acquire(provider)

@spec cancel_acquire(atom()) :: :ok

Cancel any pending acquire for the calling process on provider.

Called automatically by the entry-point helpers when a GenServer.call timeout fires so that stale waiting entries do not prevent depth from decrementing on the next release/1.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

depth(provider)

@spec depth(atom()) :: non_neg_integer()

Return the number of active (acquired) slots for provider.

Reads directly from the ETS table; never blocks the caller and never goes through the GenServer mailbox. Returns 0 when the queue is disabled (ETS table does not exist).

release(provider)

@spec release(atom()) :: :ok

Release a previously acquired slot for provider. Returns :ok.

If callers are queued for this provider, the next one in line is unblocked and inherits the slot (depth stays unchanged). When the GenServer is not running, returns :ok immediately as a no-op.

start_link(opts \\ [])