Smooth weighted round-robin allocator for outbound adapter pools.
Counters live in ETS and reset on application restart. The database remains the source of truth for membership, adapter health, and capacity.
Summary
Functions
Returns a specification to start this module under a supervisor.
Picks a member whose adapter is enabled (active = true), without health or
cap filtering. Used by enrollment-time reassign when every regular candidate
has been exhausted and we need some pin so the enrollment can proceed.
Picks a member whose adapter is currently in a usable health state, ignoring daily-cap headroom. Used by dispatch-time auto-rebind: if the pinned adapter has gone resting or inactive we need a sender that can send right now, not one that is itself resting.
Picks one eligible member for a pool and sequence version.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec pick_active_member(DripDrop.AdapterPool.t(), DripDrop.SequenceVersion.t()) :: {:ok, DripDrop.AdapterPoolMember.t()} | {:error, :pool_exhausted}
Picks a member whose adapter is enabled (active = true), without health or
cap filtering. Used by enrollment-time reassign when every regular candidate
has been exhausted and we need some pin so the enrollment can proceed.
@spec pick_healthy_member(DripDrop.AdapterPool.t(), DripDrop.SequenceVersion.t()) :: {:ok, DripDrop.AdapterPoolMember.t()} | {:error, :pool_exhausted}
Picks a member whose adapter is currently in a usable health state, ignoring daily-cap headroom. Used by dispatch-time auto-rebind: if the pinned adapter has gone resting or inactive we need a sender that can send right now, not one that is itself resting.
@spec pick_member(DripDrop.AdapterPool.t(), DripDrop.SequenceVersion.t()) :: {:ok, DripDrop.AdapterPoolMember.t()} | {:error, :pool_exhausted}
Picks one eligible member for a pool and sequence version.