Packages
reckon_db
2.3.7
5.11.0
5.10.4
5.10.3
5.10.1
5.10.0
5.9.1
5.9.0
5.8.3
5.8.2
5.8.1
5.8.0
5.7.0
5.6.1
5.6.0
5.5.5
5.5.4
5.5.3
5.5.2
5.5.1
5.5.0
5.4.0
5.2.2
5.2.1
5.2.0
5.1.0
5.0.0
4.0.0
3.1.2
3.1.1
3.0.0
2.3.7
2.3.6
2.3.5
2.3.4
2.3.3
2.3.2
2.3.1
2.3.0
2.2.2
2.2.0
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.0
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.3
1.0.2
1.0.1
1.0.0
BEAM-native Event Store built on Khepri/Ra with Raft consensus. Event sourcing, persistent subscriptions, snapshots, and automatic cluster formation via UDP multicast discovery. Ships embedded Rust NIFs for 3-15x acceleration of crypto, hashing, compression, aggregation, filter matching, and grap...
Current section
Files
Jump to
Current section
Files
src/reckon_db_subscription_backend.erl
%% @doc Behaviour for pluggable subscription-state backends.
%%
%% Subscription checkpoints track WHERE each consumer is in a stream
%% (or global log). They are written frequently — every ack — but are
%% small and not latency-critical. Most storage backends can handle
%% them fine; the behaviour exists so that a backend can choose
%% whether to keep checkpoints in its own store or delegate to the
%% Khepri control plane.
%%
%% The default implementation (`reckon_db_khepri_subscription_backend')
%% stores checkpoints in Khepri. This is the natural fit — subscription
%% state IS a control-plane concern, and Ra consensus on checkpoints
%% is exactly what you want for "don't replay already-acknowledged
%% events on leader failover."
%%
%% Fast log backends (RocksDB, custom) will typically implement
%% `reckon_db_log_backend' but NOT this — they defer to the Khepri
%% implementation. Having the behaviour explicit makes the split clean.
%%
%% @author rgfaber
-module(reckon_db_subscription_backend).
-type state() :: term().
-type subscription() :: #{
name := binary(),
selector := term(),
checkpoint := non_neg_integer(),
consumer_pid => pid() | undefined,
metadata => map()
}.
-export_type([state/0, subscription/0]).
-callback init(Opts :: map()) ->
{ok, state()} | {error, term()}.
-callback close(state()) -> ok.
-callback save(
state(),
Selector :: term(),
Name :: binary(),
Data :: map()
) -> ok | {error, term()}.
-callback remove(state(), Selector :: term(), Name :: binary()) ->
ok | {error, term()}.
-callback get(state(), Name :: binary()) ->
{ok, subscription()} | {error, not_found} | {error, term()}.
-callback list(state()) ->
{ok, [subscription()]} | {error, term()}.
-callback exists(state(), Name :: binary()) -> boolean().
-callback ack(
state(),
Name :: binary(),
Selector :: term(),
Checkpoint :: non_neg_integer()
) -> ok | {error, term()}.