# `Mailglass.RateLimiter.TableOwner`
[🔗](https://github.com/szTheory/mailglass/blob/v2.7.0/lib/mailglass/rate_limiter/table_owner.ex#L1)

Owns the `:mailglass_rate_limit` ETS table and the small amount of work that
must be serialized: missing-key admission, the bounded contention fallback,
and idle sweeping. Callers use `AtomicBucket`'s compare-and-swap fast path;
only a caller that exhausts that finite budget enters this mailbox.

## ETS opts (OTP 27+)

- `:set` — single-entry-per-key bucket
- `:public` — cross-process read/write without owner-forwarding
- `:named_table` — caller references `:mailglass_rate_limit` directly
- `read_concurrency: true` — hot read path optimization
- `write_concurrency: :auto` — OTP 27 flag for lock striping
- `decentralized_counters: true` — OTP 27 flag, per-scheduler counters

## Crash semantics

If this process crashes, BEAM deletes the ETS table. The supervisor restarts
TableOwner and `ensure_table/0` recreates the canonical table before every
owner ETS operation, including a caller that deleted the table immediately
before admission. Bucket state is intentionally ephemeral across a restart;
callers either re-admit through the replacement owner or receive the normal
bounded limiter denial, never an ETS exception.

## Reserved-singleton note

This module uses `name: __MODULE__`. It is library-internal
machinery (not a user-facing singleton) and documented in
`docs/api_stability.md` as a reserved singleton. `NoDefaultModuleNameSingleton`
has an allowlist entry for this
module.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

# `table`
*since 0.1.0* 

Returns the ETS table name. Public so tests can inspect state.

---

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