Optional, opt-in client-side rate limiting.
Triple's documented behaviour is to respond with 429 plus a
retry-after header when you exceed your plan's limits, and
Triple.Client already retries those automatically (see the :retry
option on Triple.Config). This module exists for callers who'd rather
avoid 429s in the first place — for example when bulk-enriching a
large backlog of historical transactions.
This is intentionally a simple, single-node token bucket — good enough
for a single BEAM node hammering the API from a background job. For
multi-node deployments sharing one rate budget, reach for a dedicated
library such as :hammer instead and call Triple.Client.request/4
directly after checking it yourself.
Usage
{:ok, _pid} =
Triple.RateLimiter.start_link(name: MyApp.TripleLimiter, rate: 50, per: :second)
client = Triple.new(api_key: key, rate_limiter: MyApp.TripleLimiter)Every call made through client will block the calling process (via
Process.sleep/1) until a slot is available before issuing the request.
Start it under your application's supervision tree like any other
GenServer.
Summary
Functions
Blocks the caller until a request slot is available, then consumes one.
Returns a specification to start this module under a supervisor.
Starts the rate limiter. :name and :rate are required; :per
defaults to :second (also accepts :minute or a raw millisecond
interval).
Types
@type start_option() :: {:name, GenServer.name()} | {:rate, pos_integer()} | {:per, :second | :minute | pos_integer()}
Functions
@spec acquire(GenServer.name() | pid()) :: :ok
Blocks the caller until a request slot is available, then consumes one.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec start_link([start_option()]) :: GenServer.on_start()
Starts the rate limiter. :name and :rate are required; :per
defaults to :second (also accepts :minute or a raw millisecond
interval).