Mailglass.SuppressionStore.ETS (Mailglass v1.0.0)

Copy Markdown View Source

ETS-backed implementation of Mailglass.SuppressionStore (D-28).

Test-speed + narrow production use case (single-node, read-heavy, sub-100-entry lists). Default impl remains Mailglass.SuppressionStore.Ecto โ€” adopters override via:

config :mailglass, :suppression_store, Mailglass.SuppressionStore.ETS

Key shape

ETS keys: {tenant_id, address, scope, stream_or_nil} (mirrors Ecto UNIQUE constraint (tenant_id, address, scope, COALESCE(stream, ''))).

Lookup algorithm

check/2 tries three scopes in order (matching Ecto's OR-union):

  1. {tenant_id, address, :address, nil}
  2. {tenant_id, domain(address), :domain, nil}
  3. {tenant_id, address, :address_stream, stream} (only when stream is set)

First hit wins. Expiry filter at read time (expired entries not returned).

UPSERT behaviour

record/2 with the same {tenant_id, address, scope, stream} key overwrites the existing entry (equivalent to Ecto's on_conflict: {:replace, [...]}).

Test override pattern (RESEARCH ยง5.3)

Tests scope by unique tenant_id to avoid cross-test interference โ€” no per-pid ownership needed (ETS table is global). Tests that need a clean slate between runs call Mailglass.SuppressionStore.ETS.reset/0.

Summary

Functions

Clears the ETS suppression table. Test-only helper.

Functions

reset()

(since 0.1.0)
@spec reset() :: :ok

Clears the ETS suppression table. Test-only helper.

Use this in setup blocks to ensure a clean slate between tests.