dgen_backend behaviour (DGen v0.4.0)

Copy Markdown View Source

Behaviour defining the storage backend for dgen.

A backend must implement all required callbacks to provide:

  • Transactions — serializable read-write transactions over the keyspace.
  • Key-value operations — get, set, clear, range reads, atomic adds.
  • Watches — notifications when a key changes.
  • Versionstamps — globally-ordered, unique write stamps for FIFO queuing.
  • Directory layer — tuple-key packing, range calculation, namespace isolation.

The default backend is dgen_erlfdb, which delegates to FoundationDB via the erlfdb library.

We look forward to changing the backend interface to support other systems.

Configuring the backend

Set the backend application env before starting dgen:

application:set_env(dgen, backend, my_backend).

Or in config.exs:

config :dgen, backend: MyBackend

Implementing a backend

A backend module must implement this behaviour. All watch and future operations must return {dgen_future, Ref, BackendData} tuples where Ref is a reference that will appear in a {Ref, ready} message sent to the watching process.

Types

Backends define opaque types for database handles, transaction handles, directory handles, and futures. The dgen core treats these as opaque terms and only passes them back into backend callbacks.

Summary

Functions

Runs Fun inside a transaction if Handle is a database handle, or calls Fun directly if Handle is already a transaction.

Types

db()

-type db() :: term().

dir()

-type dir() :: term().

future()

-type future() :: term().

key()

-type key() :: binary().

tenant()

-type tenant() :: {db() | tx(), dir()}.

tuple_key()

-type tuple_key() :: tuple().

tx()

-type tx() :: term().

versionstamp()

-type versionstamp() :: term().

Callbacks

add(Tx, Key, Value)

-callback add(Tx :: tx(), Key :: key(), Value :: integer()) -> ok.

add_read_conflict_key(Tx, Key)

-callback add_read_conflict_key(Tx :: tx(), Key :: key()) -> ok.

clear_range(Tx, StartKey, EndKey)

-callback clear_range(Tx :: tx(), StartKey :: key(), EndKey :: key()) -> ok.

commit(Tx)

-callback commit(Tx :: tx()) -> future().

create_transaction(Db)

-callback create_transaction(Db :: db()) -> tx().

dir_create(Db, Dir, Name)

-callback dir_create(Db :: db(), Dir :: dir(), Name :: term()) -> dir().

dir_pack(Dir, TupleKey)

-callback dir_pack(Dir :: dir(), TupleKey :: tuple_key()) -> key().

dir_pack_vs(Dir, TupleKey)

-callback dir_pack_vs(Dir :: dir(), TupleKey :: tuple_key()) -> key().

dir_range(Dir, TupleKey)

-callback dir_range(Dir :: dir(), TupleKey :: tuple_key()) -> {key(), key()}.

dir_remove(Db, Dir, Name)

-callback dir_remove(Db :: db(), Dir :: dir(), Name :: term()) -> ok.

dir_unpack(Dir, PackedKey)

-callback dir_unpack(Dir :: dir(), PackedKey :: key()) -> tuple_key().

error_code(Reason)

-callback error_code(Reason :: term()) -> integer() | error.

get(Tx, Key)

-callback get(Tx :: tx(), Key :: key()) -> future().

get_committed_version(Tx)

-callback get_committed_version(Tx :: tx()) -> integer().

get_next_tx_id(Tx)

-callback get_next_tx_id(Tx :: tx()) -> non_neg_integer().

get_range(Tx, StartKey, EndKey, Opts)

-callback get_range(Tx :: tx(), StartKey :: key(), EndKey :: key(), Opts :: list()) -> [{key(), binary()}].

get_read_version(Tx)

-callback get_read_version(Tx :: tx()) -> future().

get_versionstamp(Tx)

-callback get_versionstamp(Tx :: tx()) -> future().

is_transaction(Handle)

-callback is_transaction(Handle :: db() | tx()) -> boolean().

key_strinc(Key)

-callback key_strinc(Key :: key()) -> key().

on_error(Tx, ErrorCode)

-callback on_error(Tx :: tx(), ErrorCode :: integer()) -> future().

sandbox_open(Name, DirName)

(optional)
-callback sandbox_open(Name :: term(), DirName :: term()) -> tenant().

set(Tx, Key, Value)

-callback set(Tx :: tx(), Key :: key(), Value :: binary()) -> ok.

set_read_version(Tx, Version)

-callback set_read_version(Tx :: tx(), Version :: integer()) -> ok.

set_versionstamped_key(Tx, Key, Value)

-callback set_versionstamped_key(Tx :: tx(), Key :: key(), Value :: binary()) -> ok.

set_versionstamped_value(Tx, Key, Value)

-callback set_versionstamped_value(Tx :: tx(), Key :: key(), Value :: binary()) -> ok.

transactional(Db, Fun)

-callback transactional(Db :: db(), Fun :: fun((Tx :: tx()) -> Result)) -> Result when Result :: term().

wait(Future)

-callback wait(Future :: future()) -> term().

wait_for_all(Futures)

-callback wait_for_all(Futures :: [future()]) -> [term()].

watch(Tx, Key)

-callback watch(Tx :: tx(), Key :: key()) -> future().

watch(Tx, Key, Opts)

-callback watch(Tx :: tx(), Key :: key(), Opts :: list()) -> future().

Functions

transactional(Db, Fun)

-spec transactional(tenant(), fun((tenant()) -> Result)) -> Result when Result :: term().

Runs Fun inside a transaction if Handle is a database handle, or calls Fun directly if Handle is already a transaction.