# `Foundation.Poller`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/poller.ex#L1)

Generic polling loop with backoff and timeout controls.

# `backoff`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/poller.ex#L15)

```elixir
@type backoff() ::
  :none
  | Foundation.Backoff.Policy.t()
  | {:exponential, pos_integer(), pos_integer()}
  | (non_neg_integer() -&gt; non_neg_integer())
```

# `step_result`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/poller.ex#L8)

```elixir
@type step_result() ::
  {:ok, term()}
  | {:retry, term()}
  | {:retry, term(), non_neg_integer()}
  | {:error, term()}
  | :retry
```

# `async`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/poller.ex#L54)

```elixir
@spec async(
  (non_neg_integer() -&gt; step_result()),
  keyword()
) :: Task.t()
```

Run a polling loop in a Task.

# `await`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/poller.ex#L62)

```elixir
@spec await(Task.t(), timeout()) :: {:ok, term()} | {:error, term()}
```

Await a polling task, converting exits into error tuples.

# `run`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/poller.ex#L28)

```elixir
@spec run(
  (non_neg_integer() -&gt; step_result()),
  keyword()
) :: {:ok, term()} | {:error, term()}
```

Run a polling loop until completion, error, timeout, or max attempts.

The `step_fun` receives the current attempt (0-based).

---

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