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: trueDead-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
@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.
@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.
Returns a specification to start this module under a supervisor.
See Supervisor.
@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).
@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.