Finch.Pool.Strategy behaviour (Finch v0.22.0)
View SourceBehaviour for selecting a pool worker when multiple workers are registered under the same pool key.
When Finch is configured with count: N, N pool workers register under the same key in a
:duplicate Registry. The strategy selects one worker per request. The strategy callback and
its state are passed in request opts (e.g. pool_strategy: {MyStrategy, state}); the caller
owns and manages strategy state.
Using a built-in strategy
# Round-robin (state is an atomics counter)
counter = Finch.Pool.Strategy.RoundRobin.new()
Finch.request(req, MyFinch, pool_strategy: {Finch.Pool.Strategy.RoundRobin, counter})For performance-critical paths, pass the strategy function directly to avoid dynamic module dispatch:
Finch.request(req, MyFinch, pool_strategy: {&Finch.Pool.Strategy.RoundRobin.select/2, counter})
# Hash-based (same key always maps to same worker; useful for connection affinity)
Finch.request(req, MyFinch, pool_strategy: {Finch.Pool.Strategy.Hash, team_id})Built-in strategies: Finch.Pool.Strategy.Random, Finch.Pool.Strategy.RoundRobin, Finch.Pool.Strategy.Hash.
Custom strategy
Implement this behaviour and pass your module and state in request opts:
defmodule MyApp.LeastBusy do
@behaviour Finch.Pool.Strategy
@impl true
def select(entries, _) do
Enum.min_by(entries, fn {pid, _mod} ->
case Process.info(pid, :message_queue_len) do
{:message_queue_len, len} -> len
nil -> :infinity
end
end)
end
end
Finch.request(req, MyFinch, pool_strategy: MyApp.LeastBusy)Strategies may implement the optional new/0 or new/1 callbacks to create state; the
caller can also construct state themselves. Store state wherever makes sense (process state,
:persistent_term, Application env, etc.).
Summary
Callbacks
Optional. Returns initial state for strategies that need no argument (e.g. Random, RoundRobin).
Optional. Returns initial state for strategies that take a key or option (e.g. Hash).
Selects one pool entry from the non-empty list of registered workers.
Types
Callbacks
@callback new() :: term()
Optional. Returns initial state for strategies that need no argument (e.g. Random, RoundRobin).
Optional. Returns initial state for strategies that take a key or option (e.g. Hash).
@callback select(entries :: [pool_entry(), ...], state :: term()) :: pool_entry()
Selects one pool entry from the non-empty list of registered workers.
Called by Finch when multiple workers exist for the pool. The same state is passed for each call; the caller is responsible for any mutable state (e.g. atomics).