ETS-backed storage for Botica.Flags.Flag structs.
Architecture
- The ETS table
:botica_flagsis:publicandread_concurrency: trueso reads are O(1) and lock-free, even under heavy concurrent load. - Writes go through the GenServer (
put/1,delete/1) so that mutations are serialised and the table stays consistent. - The GenServer is also where flag lifecycle events (defined, enabled, disabled, rollout-changed) can be hooked in the future via telemetry.
Usage
In most cases you should not call this module directly — use the
Botica.Flags facade instead. Direct access is allowed when you need
the cheapest possible read and you're certain the Store is up:
iex> Botica.Flags.Store.get(:my_flag)
{:ok, %Botica.Flags.Flag{...}}
iex> Botica.Flags.Store.all()
[%Botica.Flags.Flag{...}, ...]
Summary
Functions
Direct ETS read of all flags. Returns a list (may be empty), sorted
by updated_at descending so most recently touched flags appear first.
Returns a specification to start this module under a supervisor.
Total number of registered flags. Cheap ETS count.
Remove a flag from the registry.
Direct ETS read — no GenServer round-trip. Returns {:ok, flag} or :error.
GenServer-mediated write. Serialised to avoid race conditions between concurrent definitions / enable / disable / set calls.
Returns the underlying ETS table name. Useful in tests for clearing the
registry between cases: Store.table() |> :ets.delete_all_objects().
Functions
@spec all() :: [Botica.Flags.Flag.t()]
Direct ETS read of all flags. Returns a list (may be empty), sorted
by updated_at descending so most recently touched flags appear first.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec count() :: non_neg_integer()
Total number of registered flags. Cheap ETS count.
@spec delete(atom()) :: :ok
Remove a flag from the registry.
@spec get(atom()) :: {:ok, Botica.Flags.Flag.t()} | :error
Direct ETS read — no GenServer round-trip. Returns {:ok, flag} or :error.
@spec put(Botica.Flags.Flag.t()) :: :ok
GenServer-mediated write. Serialised to avoid race conditions between concurrent definitions / enable / disable / set calls.
@spec start_link(keyword()) :: GenServer.on_start()
@spec table() :: :ets.tab()
Returns the underlying ETS table name. Useful in tests for clearing the
registry between cases: Store.table() |> :ets.delete_all_objects().