PushX.RateLimiter (PushX v0.5.0)

Copy Markdown View Source

Client-side rate limiting for push notifications.

Prevents exceeding provider rate limits by tracking requests locally. Uses a sliding window algorithm with ETS for fast, concurrent access.

Configuration

config :pushx,
  rate_limit_enabled: true,
  rate_limit_apns: 5000,      # requests per window
  rate_limit_fcm: 5000,       # requests per window
  rate_limit_window_ms: 1000  # 1 second window

Usage

Rate limiting is automatically applied when enabled. You can also check manually:

case PushX.RateLimiter.check(:apns) do
  :ok -> # Proceed with sending
  {:error, :rate_limited} -> # Back off
end

How It Works

  1. Each provider has a separate counter
  2. Requests are counted within a sliding time window
  3. When the limit is reached, new requests are rejected
  4. The window slides forward, allowing new requests

Summary

Functions

Checks if a request would be allowed without incrementing.

Checks if a request can be made and increments the counter.

Returns a specification to start this module under a supervisor.

Returns the current request count for a provider.

Returns the configured limit for a provider.

Returns remaining requests before rate limit is hit.

Resets the rate limiter for a provider. Useful for testing.

Resets all rate limiters.

Starts the rate limiter process.

Types

provider()

@type provider() :: :apns | :fcm

Functions

check(provider)

@spec check(provider()) :: :ok | {:error, :rate_limited}

Checks if a request would be allowed without incrementing.

check_and_increment(provider)

@spec check_and_increment(provider()) :: :ok | {:error, :rate_limited}

Checks if a request can be made and increments the counter.

Returns :ok if under the limit, {:error, :rate_limited} if over.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

current_count(provider)

@spec current_count(provider()) :: non_neg_integer()

Returns the current request count for a provider.

limit(atom)

@spec limit(provider()) :: pos_integer()

Returns the configured limit for a provider.

remaining(provider)

@spec remaining(provider()) :: non_neg_integer()

Returns remaining requests before rate limit is hit.

reset(provider)

@spec reset(provider()) :: :ok

Resets the rate limiter for a provider. Useful for testing.

reset_all()

@spec reset_all() :: :ok

Resets all rate limiters.

start_link(opts \\ [])

Starts the rate limiter process.