Module khepri

Khepri high-level and cluster management API.

Description

Khepri high-level and cluster management API.

This module exposes the high-level API to manipulate data and the cluster management API.

Cluster management

Starting a Ra system

The default store is based on Ra's default system. You need to change the Ra application configuration if you want to set settings. That said, it is recommended to start your own Ra system. This way, even though Ra is already running, you can choose where the Khepri data should be stored. This is also required if you need to run multiple database instances in parallel.

Here is a quick start example:

%% We start Khepri. Ra is also started because Khepri depends on it.
{ok, _} = application:ensure_all_started(khepri),
 
%% We define the configuration of the Ra system for our database. Here, we
%% only care about the directory where data will be written.
RaSystem = my_ra_system,
RaSystemDataDir = "/path/to/storage/dir",
DefaultSystemConfig = ra_system:default_config(),
RaSystemConfig = DefaultSystemConfig#{name => RaSystem,
                                      data_dir => RaSystemDataDir,
                                      wal_data_dir => RaSystemDataDir,
                                      names => ra_system:derive_names(
                                                 RaSystem)},
 
%% The configuration is ready, let's start the Ra system.
{ok, _RaSystemPid} = ra_system:start(RaSystemConfig),
 
%% At last we can start Khepri! We need to choose a name for the Ra cluster
%% running in the Ra system started above. This must be an atom.
RaClusterName = my_khepri_db,
RaClusterFriendlyName = "My Khepri DB",
{ok, StoreId} = khepri:start(
                  RaSystem,
                  RaClusterName,
                  RaClusterFriendlyName),
 
%% The Ra cluster name is our "store ID" used everywhere in the Khepri API.
khepri:insert(StoreId, [stock, wood], 156).

Please refer to Ra documentation to learn more about Ra systems and Ra clusters.

Managing Ra cluster members

To add a member to your Ra cluster:

khepri:add_member(
  RaSystem,
  RaClusterName,
  RaClusterFriendlyName,
  NewMemberErlangNodename).

To remove a member from your Ra cluster:

khepri:remove_member(
  RaClusterName,
  MemberErlangNodenameToRemove).

Data manipulation

See individual functions for more details.

Data Types

error()

error(Type) = {error, Type}

Return value of a failed command or query.

error()

error() = error(any())

ok()

ok(Type) = {ok, Type}

store_id()

store_id() = ra:cluster_name()

ID of a Khepri store.

Function Index

start/0
start/1
start/3
add_member/2
add_member/4
remove_member/1
remove_member/2
reset/2
members/1
locally_known_members/1
nodes/1
locally_known_nodes/1
get_store_ids/0
create/2Creates a specific tree node in the tree structure only if it does not exist.
create/3Creates a specific tree node in the tree structure only if it does not exist.
insert/2Creates or modifies a specific tree node in the tree structure.
insert/3Creates or modifies a specific tree node in the tree structure.
update/2Updates a specific tree node in the tree structure only if it already exists.
update/3Updates a specific tree node in the tree structure only if it already exists.
compare_and_swap/3Updates a specific tree node in the tree structure only if it already exists and its data matches the given DataPattern.
compare_and_swap/4Updates a specific tree node in the tree structure only if it already exists and its data matches the given DataPattern.
clear_payload/1Clears the payload of an existing specific tree node in the tree structure.
clear_payload/2Clears the payload of an existing specific tree node in the tree structure.
delete/1Deletes all tree nodes matching the path pattern.
delete/2Deletes all tree nodes matching the path pattern.
get/1Returns all tree nodes matching the path pattern.
get/2Returns all tree nodes matching the path pattern.
get/3Returns all tree nodes matching the path pattern.
exists/1Returns true if the tree node pointed to by the given path exists, otherwise false.
exists/2Returns true if the tree node pointed to by the given path exists, otherwise false.
has_data/1Returns true if the tree node pointed to by the given path has a data payload, otherwise false.
has_data/2Returns true if the tree node pointed to by the given path has a data payload, otherwise false.
list/1
list/2
find/2Finds tree nodes below Path which match the given Condition.
find/3Finds tree nodes under Path which match the given Condition.
transaction/1
transaction/2
transaction/3
clear_store/0
clear_store/1
no_payload/0Returns ?NO_PAYLOAD.
data_payload/1Returns ?DATA_PAYLOAD(Term).
info/0
info/1

Function Details

start/0

start() -> {ok, store_id()} | {error, any()}

start/1

start(RaSystem::atom()) -> {ok, store_id()} | {error, any()}

start/3

start(RaSystem::atom(), ClusterName::ra:cluster_name(), FriendlyName::string()) -> {ok, store_id()} | {error, any()}

add_member/2

add_member(RaSystem, NewNode) -> any()

add_member/4

add_member(RaSystem, ClusterName, FriendlyName, NewNode) -> any()

remove_member/1

remove_member(NodeToRemove) -> any()

remove_member/2

remove_member(ClusterName, NodeToRemove) -> any()

reset/2

reset(RaSystem, ClusterName) -> any()

members/1

members(ClusterName) -> any()

locally_known_members/1

locally_known_members(ClusterName) -> any()

nodes/1

nodes(ClusterName) -> any()

locally_known_nodes/1

locally_known_nodes(ClusterName) -> any()

get_store_ids/0

get_store_ids() -> [store_id()]

create/2

create(Path, Data) -> ok | error()

Creates a specific tree node in the tree structure only if it does not exist.

Calling this function is the same as calling create(StoreId, Path, Data) with the default store ID.

See also: create/3.

create/3

create(StoreId, Path, Data) -> ok | error()

returns: a single "ok" atom or an "error" tuple, unlike khepri_machine:put/3.

Creates a specific tree node in the tree structure only if it does not exist.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

The Path is the modified to include a #if_node_exists{exists = false} condition on its last component.

Once the path is possibly converted to a list of node names and conditions and udpated, it calls khepri_machine:put/3.

See also: khepri_machine:put/3.

insert/2

insert(Path, Data) -> ok | error()

Creates or modifies a specific tree node in the tree structure.

Calling this function is the same as calling insert(StoreId, Path, Data) with the default store ID.

See also: insert/3.

insert/3

insert(StoreId, Path, Data) -> ok | error()

returns: a single "ok" atom or an "error" tuple, unlike khepri_machine:put/3.

Creates or modifies a specific tree node in the tree structure.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

Once the path is normalized to a list of tree node names and conditions and updated, it calls khepri_machine:put/3.

See also: khepri_machine:put/3.

update/2

update(Path, Data) -> ok | error()

Updates a specific tree node in the tree structure only if it already exists.

Calling this function is the same as calling update(StoreId, Path, Data) with the default store ID.

See also: update/3.

update/3

update(StoreId, Path, Data) -> ok | error()

returns: a single "ok" atom or an "error" tuple, unlike khepri_machine:put/3.

Updates a specific tree node in the tree structure only if it already exists.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

The Path is the modified to include a #if_node_exists{exists = true} condition on its last component.

Once the path is possibly converted to a list of node names and conditions and udpated, it calls khepri_machine:put/3.

See also: khepri_machine:put/3.

compare_and_swap/3

compare_and_swap(Path, DataPattern, Data) -> ok | error()

Updates a specific tree node in the tree structure only if it already exists and its data matches the given DataPattern.

Calling this function is the same as calling compare_and_swap(StoreId, Path, DataPattern, Data) with the default store ID.

See also: create/3.

compare_and_swap/4

compare_and_swap(StoreId, Path, DataPattern, Data) -> ok | error()

returns: a single "ok" atom or an "error" tuple, unlike khepri_machine:put/3.

Updates a specific tree node in the tree structure only if it already exists and its data matches the given DataPattern.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

The Path is the modified to include a #if_data_matches{pattern = DataPattern} condition on its last component.

Once the path is possibly converted to a list of node names and conditions and udpated, it calls khepri_machine:put/3.

See also: khepri_machine:put/3.

clear_payload/1

clear_payload(Path) -> ok | error()

Clears the payload of an existing specific tree node in the tree structure.

Calling this function is the same as calling clear_payload(StoreId, Path) with the default store ID.

See also: create/3.

clear_payload/2

clear_payload(StoreId, Path) -> ok | error()

returns: a single "ok" atom or an "error" tuple, unlike khepri_machine:put/3.

Clears the payload of an existing specific tree node in the tree structure.

In other words, the payload is set to ?NO_PAYLOAD.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

Once the path is possibly converted to a list of node names and conditions and udpated, it calls khepri_machine:put/3.

See also: khepri_machine:put/3.

delete/1

delete(PathPattern) -> ok | error()

Deletes all tree nodes matching the path pattern.

Calling this function is the same as calling delete(StoreId, PathPattern) with the default store ID.

See also: delete/2.

delete/2

delete(StoreId, PathPattern) -> ok | error()

returns: a single "ok" atom or an "error" tuple, unlike khepri_machine:delete/2.

Deletes all tree nodes matching the path pattern.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

Once the path is possibly converted to a list of node names and conditions, it calls khepri_machine:delete/2.

See also: delete/2.

get/1

get(PathPattern) -> Result

Returns all tree nodes matching the path pattern.

Calling this function is the same as calling get(StoreId, PathPattern) with the default store ID.

See also: get/3.

get/2

get(StoreId, PathPattern) -> Result

get(PathPattern, Options) -> Result

Returns all tree nodes matching the path pattern.

This function accepts the following two forms:

See also: get/3.

get/3

get(StoreId, PathPattern, Options) -> Result

Returns all tree nodes matching the path pattern.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

Once the path is possibly converted to a list of node names and conditions, it calls khepri_machine:get/3.

See also: khepri_machine:get/3.

exists/1

exists(Path) -> Exists

Returns true if the tree node pointed to by the given path exists, otherwise false.

Calling this function is the same as calling exists(StoreId, Path) with the default store ID.

See also: exists/2.

exists/2

exists(StoreId, Path) -> Exists

Returns true if the tree node pointed to by the given path exists, otherwise false.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

The Path must point to a specific tree node and can't match multiple nodes.

This function calls get/3 and interpret its result.

See also: get/3.

has_data/1

has_data(Path) -> HasData

Returns true if the tree node pointed to by the given path has a data payload, otherwise false.

Calling this function is the same as calling has_data(StoreId, Path) with the default store ID.

See also: has_data/2.

has_data/2

has_data(StoreId, Path) -> HasData

Returns true if the tree node pointed to by the given path has a data payload, otherwise false.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

The Path must point to a specific tree node and can't match multiple nodes.

This function calls get/3 and interpret its result.

See also: get/3.

list/1

list(Path::khepri_path:pattern() | string()) -> khepri_machine:result()

list/2

list(StoreId::store_id(), Path::khepri_path:pattern() | string()) -> khepri_machine:result()

find/2

find(Path, Condition) -> Result

Finds tree nodes below Path which match the given Condition.

This function operates on the default store.

See also: find/3.

find/3

find(StoreId, Path, Condition) -> Result

StoreId: the name of the Ra cluster.
Path: the path indicating where to start the search from.
Condition: the condition nodes must match to be part of the result.

returns: an "ok" tuple with a map with zero, one or more entries, or an "error" tuple.

Finds tree nodes under Path which match the given Condition.

The Path can be provided as a list of node names and conditions or as a string. See khepri_path:from_string/1.

Nodes are searched deeply under the given Path, not only among direct child nodes.

Example:
%% Find nodes with data under `/foo/bar'.
Result = khepri:find(
           ra_cluster_name,
           [foo, bar],
           #if_has_data{has_data = true}),
 
%% Here is the content of `Result'.
{ok, #{[foo, bar, baz] => #{data => baz_value,
                            payload_version => 2,
                            child_list_version => 1,
                            child_list_length => 0},
       [foo, bar, deep, under, qux] => #{data => qux_value,
                                         payload_version => 1,
                                         child_list_version => 1,
                                         child_list_length => 0}}} = Result.

transaction/1

transaction(Fun) -> Ret

transaction/2

transaction(StoreId, Fun) -> Ret

transaction(Fun, ReadWrite) -> Ret

transaction/3

transaction(StoreId, Fun, ReadWrite) -> Ret

clear_store/0

clear_store() -> ok | error()

clear_store/1

clear_store(StoreId::store_id()) -> ok | error()

no_payload/0

no_payload() -> none

Returns ?NO_PAYLOAD.

This is a helper for cases where using macros is inconvenient, like in an Erlang shell.

data_payload/1

data_payload(Term) -> {data, Term}

Returns ?DATA_PAYLOAD(Term).

This is a helper for cases where using macros is inconvenient, like in an Erlang shell.

info/0

info() -> any()

info/1

info(StoreId::store_id()) -> ok


Generated by EDoc