Botica.Flags.Persistence behaviour (Botica v2.2.0)

Copy Markdown View Source

Behaviour for persisting feature flags outside of the ETS cache.

The Botica.Flags.Store GenServer uses the configured persistence adapter as the source of truth at boot (load_all/0) and writes through on every mutation (save_flag/1, delete_flag/1). The ETS table remains the in-memory read cache: O(1) reads without a GenServer round-trip.

Built-in adapters

Custom adapters

defmodule MyApp.FlagPersistence do
  @behaviour Botica.Flags.Persistence

  @impl true
  def load_all, do: {:ok, []}

  @impl true
  def save_flag(_flag), do: :ok

  @impl true
  def delete_flag(_name), do: :ok
end

Configure the active adapter in :botica application env:

config :botica, :flags_persistence, [
  adapter: MyApp.FlagPersistence,
  opts: []
]

Summary

Callbacks

Removes a flag from the persistent store.

Loads every persisted flag. Called once at Store boot to populate the ETS cache. Returns {:ok, [Flag.t()]} or {:error, term()}.

Persists a single flag. Called on every Store mutation.

Functions

Returns the configured persistence adapter from application env. Defaults to Botica.Flags.Persistence.Disk with no options.

Disables persistence entirely (adapter: false). The Store then behaves as a pure in-memory registry — useful for tests and ephemeral processes.

Callbacks

delete_flag(atom)

@callback delete_flag(atom()) :: :ok | {:error, term()}

Removes a flag from the persistent store.

load_all()

@callback load_all() :: {:ok, [Botica.Flags.Flag.t()]} | {:error, term()}

Loads every persisted flag. Called once at Store boot to populate the ETS cache. Returns {:ok, [Flag.t()]} or {:error, term()}.

save_flag(t)

@callback save_flag(Botica.Flags.Flag.t()) :: :ok | {:error, term()}

Persists a single flag. Called on every Store mutation.

Functions

configured()

@spec configured() :: {module(), keyword()}

Returns the configured persistence adapter from application env. Defaults to Botica.Flags.Persistence.Disk with no options.

Configuration

config :botica, :flags_persistence, [
  adapter: Botica.Flags.Persistence.Disk,
  opts: [path: "/var/lib/botica/flags.json"]
]

enabled?()

@spec enabled?() :: boolean()

Disables persistence entirely (adapter: false). The Store then behaves as a pure in-memory registry — useful for tests and ephemeral processes.

config :botica, :flags_persistence, adapter: false