Power-of-two-choices with a least-frequently-used tiebreak.
Picks two distinct random channel indices and returns the one with the lower selection count, then increments that count. This spreads load more evenly than pure random under skewed workloads.
Load is tracked in a lock-free :atomics array (one counter per slot) rather
than in ETS, so selection performs no ETS read or write in the hot path —
avoiding the write-lock contention that an :ets.update_element on every
call would cause under concurrency.
Sizing and scaling
The atomics array is fixed-size at creation. It is sized to
max(pool_size, max_slots) where max_slots defaults to 1024 and is
configurable:
config :grpc_connection_pool, power_of_two_max_slots: 2048If the pool ever scales beyond the array size, select/3 falls back to a
pure power-of-two-choices pick (no counter) for the out-of-range indices, so
it stays correct (never crashes) — it just loses the LFU signal for those
extra slots.