AuroraMeter. Storage behaviour
(Aurora Meter v0.3.0)
View Source
Behaviour for persisting Aurora Meter state, plus dispatch helpers that route to
the configured adapter (AuroraMeter.Config.storage/0, default
AuroraMeter.Storage.Ecto).
Only a Postgres/Ecto adapter ships in v1; this behaviour keeps the door open for others without building through it now.
Summary
Types
A counter delta to add: value = value + delta.
A counter snapshot to persist. feature may be an atom or string.
A total as returned after adding deltas. feature is a string.
A raw usage event to persist.
A day-bucket delta to add.
A day bucket as read back: %{date: Date.t(), value: integer()}.
A day-bucket snapshot to persist.
A day-bucket total as returned after adding deltas.
Functions
Adds deltas to counters (value = value + delta, inserting at delta when
the row is new) and returns the resulting totals. This is what makes
cluster-wide counting correct: each node writes only what it added.
Adds deltas to day buckets and returns the resulting totals. See add_counters/1.
Fetches a tenant's subscription straight from storage (uncached), or nil.
Appends raw usage events (durable mode / audit).
Loads a single flushed counter value, or nil if absent.
Loads a single flushed day-bucket value, or nil if absent.
Loads the flushed day buckets for a feature between two dates (inclusive), oldest first.
Inserts or updates a tenant's subscription (upsert on tenant_key) and evicts
it from the subscription cache on every node.
Returns all counter snapshots for a period (used by Pro rollups).
Sets counter snapshots to absolute values by {tenant_key, feature, period_start}. For backfills and test fixtures; the flusher uses
add_counters/1 so that nodes add up instead of overwriting one another.
Upserts day-bucket snapshots (absolute values) by {tenant_key, feature, date}.
Types
@type counter_delta() :: %{ tenant_key: String.t(), feature: atom() | String.t(), period_start: DateTime.t(), delta: integer() }
A counter delta to add: value = value + delta.
@type counter_row() :: %{ tenant_key: String.t(), feature: atom() | String.t(), period_start: DateTime.t(), value: integer() }
A counter snapshot to persist. feature may be an atom or string.
@type counter_total() :: %{ tenant_key: String.t(), feature: String.t(), period_start: DateTime.t(), value: integer() }
A total as returned after adding deltas. feature is a string.
@type event_row() :: %{ :tenant_key => String.t(), :feature => atom() | String.t(), optional(:quantity) => integer(), optional(:metadata) => map() }
A raw usage event to persist.
@type history_delta() :: %{ tenant_key: String.t(), feature: atom() | String.t(), date: Date.t(), delta: integer() }
A day-bucket delta to add.
A day bucket as read back: %{date: Date.t(), value: integer()}.
@type history_row() :: %{ tenant_key: String.t(), feature: atom() | String.t(), date: Date.t(), value: integer() }
A day-bucket snapshot to persist.
@type history_total() :: %{ tenant_key: String.t(), feature: String.t(), date: Date.t(), value: integer() }
A day-bucket total as returned after adding deltas.
Callbacks
@callback add_counters([counter_delta()]) :: {:ok, [counter_total()]}
@callback add_history([history_delta()]) :: {:ok, [history_total()]}
@callback get_subscription(String.t()) :: AuroraMeter.Schema.Subscription.t() | nil
@callback insert_events([event_row()]) :: :ok
@callback load_counter(String.t(), atom() | String.t(), DateTime.t()) :: integer() | nil
@callback put_subscription(map()) :: {:ok, AuroraMeter.Schema.Subscription.t()} | {:error, Ecto.Changeset.t()}
@callback stream_counters(DateTime.t()) :: [AuroraMeter.Schema.Counter.t()]
@callback upsert_counters([counter_row()]) :: :ok
@callback upsert_history([history_row()]) :: :ok
Functions
@spec add_counters([counter_delta()]) :: {:ok, [counter_total()]}
Adds deltas to counters (value = value + delta, inserting at delta when
the row is new) and returns the resulting totals. This is what makes
cluster-wide counting correct: each node writes only what it added.
@spec add_history([history_delta()]) :: {:ok, [history_total()]}
Adds deltas to day buckets and returns the resulting totals. See add_counters/1.
@spec get_subscription(String.t()) :: AuroraMeter.Schema.Subscription.t() | nil
Fetches a tenant's subscription straight from storage (uncached), or nil.
@spec insert_events([event_row()]) :: :ok
Appends raw usage events (durable mode / audit).
@spec load_counter(String.t(), atom() | String.t(), DateTime.t()) :: integer() | nil
Loads a single flushed counter value, or nil if absent.
Loads a single flushed day-bucket value, or nil if absent.
@spec load_history_range(String.t(), atom() | String.t(), Date.t(), Date.t()) :: [ history_point() ]
Loads the flushed day buckets for a feature between two dates (inclusive), oldest first.
@spec put_subscription(map()) :: {:ok, AuroraMeter.Schema.Subscription.t()} | {:error, Ecto.Changeset.t()}
Inserts or updates a tenant's subscription (upsert on tenant_key) and evicts
it from the subscription cache on every node.
@spec stream_counters(DateTime.t()) :: [AuroraMeter.Schema.Counter.t()]
Returns all counter snapshots for a period (used by Pro rollups).
@spec upsert_counters([counter_row()]) :: :ok
Sets counter snapshots to absolute values by {tenant_key, feature, period_start}. For backfills and test fixtures; the flusher uses
add_counters/1 so that nodes add up instead of overwriting one another.
@spec upsert_history([history_row()]) :: :ok
Upserts day-bucket snapshots (absolute values) by {tenant_key, feature, date}.