# `Foundation.Semaphore.Limiter`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/semaphore/limiter.ex#L1)

Blocking counting semaphore with exponential backoff.

# `semaphore_name`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/semaphore/limiter.ex#L14)

```elixir
@type semaphore_name() :: {Foundation.Semaphore.Limiter, term(), pos_integer()}
```

# `get_semaphore`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/semaphore/limiter.ex#L20)

```elixir
@spec get_semaphore(pos_integer()) :: semaphore_name()
```

Return the semaphore name for the default key and max connections.

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

```elixir
@spec get_semaphore(term(), pos_integer()) :: semaphore_name()
```

Return the semaphore name for a key and max connections.

# `with_semaphore`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/semaphore/limiter.ex#L37)

```elixir
@spec with_semaphore(pos_integer(), (-&gt; result)) :: result when result: any()
```

Execute `fun` while holding a semaphore for `max_connections`.

# `with_semaphore`
[🔗](https://github.com/nshkrdotcom/foundation/blob/v0.2.1/lib/foundation/semaphore/limiter.ex#L68)

```elixir
@spec with_semaphore(term(), pos_integer(), keyword(), (-&gt; result)) :: result
when result: any()
```

Execute `fun` while holding a keyed semaphore with options.

Options:
  * `:registry` - counting semaphore registry (default: `Counting.default_registry/0`)
  * `:backoff` - backoff options or `Backoff.Policy` (default: exponential 2ms-50ms, 25% jitter)
  * `:sleep_fun` - sleep function (default: `&Process.sleep/1`)
  * `:max_backoff_exponent` - cap for exponential backoff attempts (default: 20)

---

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