# `Gemini.RateLimiter.RetryManager`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.15.0/lib/gemini/rate_limiter/retry_manager.ex#L1)

Manages retry logic with backoff strategies.

Handles:
- 429 rate limit responses with server-provided RetryInfo delay
- Transient 5xx errors with exponential backoff and jitter
- Network/transport errors with bounded retries

Coordinates with the rate limiter state to avoid double retries.

# `response_status`

```elixir
@type response_status() :: :success | :rate_limited | :transient | :permanent
```

# `retry_result`

```elixir
@type retry_result() ::
  {:ok, term()}
  | {:error, {:rate_limited, DateTime.t(), map()}}
  | {:error, {:transient_failure, pos_integer(), term()}}
  | {:error, term()}
```

# `calculate_backoff`

```elixir
@spec calculate_backoff(pos_integer(), Gemini.RateLimiter.Config.t()) :: pos_integer()
```

Calculate backoff duration for a given attempt.

Uses exponential backoff with jitter: base * 2^(attempt-1) * (1 ± jitter)

# `classify_response`

```elixir
@spec classify_response({:ok, term()} | {:error, term()}) :: response_status()
```

Classify a response to determine retry behavior.

## Returns

- `:success` - Request succeeded
- `:rate_limited` - 429 response, should wait for RetryInfo delay
- `:transient` - Retryable error (5xx, network)
- `:permanent` - Non-retryable error (4xx except 429)

# `execute_with_retry`

```elixir
@spec execute_with_retry(
  (-&gt; {:ok, term()} | {:error, term()}),
  Gemini.RateLimiter.State.state_key(),
  Gemini.RateLimiter.Config.t(),
  keyword()
) :: retry_result()
```

Execute a request function with retry handling.

## Parameters

- `request_fn` - Zero-arity function that makes the actual request
- `state_key` - Key for rate limit state tracking
- `config` - Rate limiter configuration
- `opts` - Additional options

## Options

- `:attempt` - Current attempt number (internal use)

## Returns

- `{:ok, response}` - Request succeeded
- `{:error, {:rate_limited, retry_at, details}}` - Rate limited, wait until retry_at
- `{:error, {:transient_failure, attempts, last_error}}` - Transient failure after max attempts
- `{:error, reason}` - Permanent failure

# `extract_retry_info`

```elixir
@spec extract_retry_info({:error, term()}) :: map()
```

Extract retry delay from a 429 error response.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
