Quant.Explorer.RateLimiting.Behaviour behaviour (quant v0.1.0-alpha.1)
Behaviour for rate limiting backends.
This behaviour defines a flexible interface for rate limiting that can support various algorithms and backends (ETS, Redis, GenServer, etc.) and different provider-specific requirements.
Supported Rate Limiting Patterns
Simple Rate Limiting
- Fixed window: N requests per time window
- Sliding window: N requests in any sliding time window
- Token bucket: Consume tokens at variable rates
Provider-Specific Patterns
- Binance: Weight-based requests (different endpoints have different weights)
- Yahoo Finance: IP-based limits with burst allowance
- Alpha Vantage: API key-based with daily/monthly quotas
- CoinGecko: Tiered limits based on API plan
Rate Limit Types
:requests_per_minute- Standard RPM limit:requests_per_second- High-frequency limit:requests_per_hour- Hourly quotas:requests_per_day- Daily quotas:weighted_requests- Weight-based limiting (Binance style):burst_allowance- Allow bursts with recovery
Summary
Callbacks
Checks if a request is allowed and records it if so.
Checks if a request would be allowed without consuming the limit.
Cleans up expired entries and performs maintenance.
Records a request consumption without checking.
Gets current limit status for a provider/endpoint combination.
Returns statistics about rate limiting (requests, violations, etc.).
Initializes the rate limiter backend.
Resets limits for a provider/endpoint (useful for testing or admin operations).
Sets up distributed coordination (for Redis, etc.).
Handles backend-specific configuration updates.
Functions
Helper function to create rate limit configurations.
Helper function to create a basic request info structure.
Types
@type limit_config() :: %{ :endpoint => atom(), :type => limit_type(), :limit => pos_integer(), :weight => pos_integer(), :window_ms => pos_integer(), optional(:burst_size) => pos_integer(), optional(:recovery_rate) => pos_integer() }
@type limit_type() ::
:requests_per_minute
| :requests_per_second
| :requests_per_hour
| :requests_per_day
| :weighted_requests
| :burst_allowance
@type provider() :: atom()
@type rate_limit_result() :: :ok | {:error, :rate_limited} | {:error, term()}
@type remaining_info() :: %{ remaining: non_neg_integer(), reset_time: DateTime.t(), retry_after_ms: pos_integer() }
@type weight() :: pos_integer()
Callbacks
@callback check_and_consume(request_info(), limit_config(), state :: term()) :: {rate_limit_result(), remaining_info(), new_state :: term()}
Checks if a request is allowed and records it if so.
This is the primary function that combines check and record operations for atomic rate limiting.
@callback check_limit(request_info(), limit_config(), state :: term()) :: {rate_limit_result(), remaining_info(), state :: term()}
Checks if a request would be allowed without consuming the limit.
Useful for pre-flight checks or API exploration.
Cleans up expired entries and performs maintenance.
@callback consume_limit(request_info(), limit_config(), state :: term()) :: {remaining_info(), new_state :: term()}
Records a request consumption without checking.
Useful for tracking requests made outside the normal flow.
@callback get_limit_status(provider(), endpoint(), state :: term()) :: {remaining_info(), state :: term()}
Gets current limit status for a provider/endpoint combination.
Returns statistics about rate limiting (requests, violations, etc.).
Initializes the rate limiter backend.
Returns {:ok, state} on success, {:error, reason} on failure.
@callback reset_limits(provider(), endpoint() | :all, state :: term()) :: {:ok, new_state :: term()}
Resets limits for a provider/endpoint (useful for testing or admin operations).
@callback setup_distributed(nodes :: [node()], state :: term()) :: {:ok, new_state :: term()} | {:error, term()}
Sets up distributed coordination (for Redis, etc.).
@callback update_config(new_config :: keyword(), state :: term()) :: {:ok, new_state :: term()} | {:error, term()}
Handles backend-specific configuration updates.
Functions
@spec limit_config(limit_type(), pos_integer(), keyword()) :: %{ :type => limit_type(), :limit => pos_integer(), :weight => pos_integer(), :window_ms => pos_integer(), optional(:burst_size) => pos_integer(), optional(:recovery_rate) => pos_integer() }
Helper function to create rate limit configurations.
@spec request_info(provider(), endpoint(), keyword()) :: request_info()
Helper function to create a basic request info structure.