Khepri service and cluster management API.
This module provides the public API for the service and cluster management.
For convenience, some functions of this API are repeated in the khepri
module for easier access.
A Khepri store is a Ra server inside a Ra cluster. The Khepri store and the Ra cluster share the same name in fact. The only constraint is that the name must be an atom, even though Ra accepts other Erlang types as cluster names.
By default, Khepri uses khepri
as the store ID (and thus Ra cluster name).
This default can be overridden using an argument to the start()
functions
or the default_store_id
application environment variable.
{ok, khepri} = khepri:start().
{ok, my_store} = khepri:start("/var/lib/khepri", my_store).
ok = application:set_env(
khepri, default_store_id, my_store, [{persistent, true}]),
{ok, my_store} = khepri:start().
A Ra server relies on a Ra system to provide various functions and to configure the directory where the data should be stored on disk.
By default, Khepri will configure its own Ra system to write data under
khepri#Nodename
in the current working directory, where Nodename
is
the name of the Erlang node.
{ok, StoreId} = khepri:start().
%% If the Erlang node was started without distribution (the default), the
%% statement above will start a Ra system called like the store (`khepri')
%% and will use the `khepri#nonode@nohost' directory.
The default data directory or Ra system name can be overridden using an
argument to the start()
or the default_ra_system
application environment
variable. Both a directory (string or binary) or the name of an already
running Ra system are accepted.
{ok, StoreId} = khepri:start(my_ra_system).
ok = application:set_env(
khepri, default_ra_system, "/var/lib/khepri", [{persistent, true}]),
{ok, StoreId} = khepri:start().
Please refer to Ra documentation to learn more about Ra systems and Ra clusters.
A Khepri/Ra cluster can be expanded by telling a node to join a remote cluster. Note that the Khepri store/Ra server to add to the cluster must run before it can join.
%% Start the local Khepri store.
{ok, StoreId} = khepri:start().
%% Join a remote cluster.
ok = khepri_cluster:join(RemoteNode).
To remove the local Khepri store node from the cluster, it must be reset.
%% Start the local Khepri store.
ok = khepri_cluster:reset().
incomplete_ra_server_config() = map()
A Ra server config map.
This configuration map can lack the required parameters, Khepri will fill them if necessary. Important parameters for Khepri (e.g.machine
) will be
overridden anyway.
start/0 | Starts a store. |
start/1 | Starts a store. |
start/2 | Starts a store. |
start/3 | Starts a store. |
stop/0 | Stops a store. |
stop/1 | Stops a store. |
join/1 | Adds the local running Khepri store to a remote cluster. |
join/2 | Adds the local running Khepri store to a remote cluster. |
reset/0 | Resets the store on this Erlang node. |
reset/1 | Resets the store on this Erlang node. |
reset/2 | Resets the store on this Erlang node. |
get_default_ra_system_or_data_dir/0 | Returns the default Ra system name or data directory. |
get_default_store_id/0 | Returns the default Khepri store ID. |
members/0 | Returns the list of Ra members that are part of the cluster. |
members/1 | Returns the list of Ra members that are part of the cluster. |
members/2 | Returns the list of Ra members that are part of the cluster. |
locally_known_members/0 | Returns the list of Ra members that are part of the cluster. |
locally_known_members/1 | Returns the list of Ra members that are part of the cluster. |
locally_known_members/2 | Returns the list of Ra members that are part of the cluster. |
nodes/0 | Returns the list of Erlang nodes that are part of the cluster. |
nodes/1 | Returns the list of Erlang nodes that are part of the cluster. |
nodes/2 | Returns the list of Erlang nodes that are part of the cluster. |
locally_known_nodes/0 | Returns the list of Erlang nodes that are part of the cluster. |
locally_known_nodes/1 | Returns the list of Erlang nodes that are part of the cluster. |
locally_known_nodes/2 | Returns the list of Erlang nodes that are part of the cluster. |
wait_for_leader/0 | Waits for a leader to be elected. |
wait_for_leader/1 | Waits for a leader to be elected. |
wait_for_leader/2 | Waits for a leader to be elected. |
get_store_ids/0 | Returns the list of running stores. |
is_store_running/1 | Indicates if StoreId is running or not. |
start() -> Ret
Ret = khepri:ok(StoreId) | khepri:error()
StoreId = khepri:store_id()
Starts a store.
Calling this function is the same as callingstart(DefaultRaSystem)
where
DefaultRaSystem
is returned by get_default_ra_system_or_data_dir/0
.
See also: start/1, ra_server:ra_server_config().
start(RaSystemOrDataDir::RaSystem | DataDir) -> Ret
RaSystem = atom()
DataDir = file:filename_all()
Ret = khepri:ok(StoreId) | khepri:error()
StoreId = khepri:store_id()
Starts a store.
Calling this function is the same as callingstart(RaSystemOrDataDir,
DefaultStoreId)
where DefaultStoreId
is returned by get_default_store_id/0
.
See also: start/2.
start(RaSystemOrDataDir::RaSystem | DataDir, StoreIdOrRaServerConfig::StoreId | RaServerConfig) -> Ret
RaSystem = atom()
DataDir = file:filename_all()
StoreId = khepri:store_id()
RaServerConfig = incomplete_ra_server_config()
Ret = khepri:ok(StoreId) | khepri:error()
Starts a store.
Calling this function is the same as callingstart(RaSystemOrDataDir,
StoreIdOrRaServerConfig, DefaultTimeout)
where DefaultTimeout
is
returned by khepri_app:get_default_timeout/0
.
See also: start/3.
start(RaSystemOrDataDir::RaSystem | DataDir, StoreIdOrRaServerConfig::StoreId | RaServerConfig, Timeout) -> Ret
RaSystem = atom()
DataDir = file:filename_all()
StoreId = khepri:store_id()
RaServerConfig = incomplete_ra_server_config()
Timeout = timeout()
Ret = khepri:ok(StoreId) | khepri:error()
returns: the ID of the started store in an "ok" tuple, or an error tuple if the store couldn't be started.
Starts a store.
It accepts either a Ra system name (atom) or a data directory (string or binary) as its first argument. If a Ra system name is given, that Ra system must be running when this function is called. If a data directory is given, a new Ra system will be started, using this directory. The directory will be created automatically if it doesn't exist. The Ra system will use the same name as the Khepri store.
It accepts a Khepri store ID or a Ra server configuration as its second argument. If a store ID is given, a Ra server configuration will be created based on it. If a Ra server configuration is given, the name of the Khepri store will be derived from it.
If this is a new store, the Ra server is started and an election is triggered so that it becomes its own leader and is ready to process commands and queries.
If the store was started in the past and stopped, it will be restarted. In this case,RaServerConfig
will be ignored. Ra will take care of the
eletion automatically.
stop() -> Ret
Ret = ok | khepri:error()
Stops a store.
Calling this function is the same as callingstop(DefaultStoreId)
where DefaultStoreId
is returned by get_default_store_id/0
.
See also: stop/1.
stop(StoreId) -> Ret
StoreId = khepri:store_id()
Ret = ok | khepri:error()
StoreId
: the ID of the store to stop.
returns: ok
if it succeeds, an error tuple otherwise.
Stops a store.
join(RemoteNode::RemoteMember | RemoteNode) -> Ret
RemoteMember = ra:server_id()
RemoteNode = node()
Ret = ok | khepri:error()
Adds the local running Khepri store to a remote cluster.
This function accepts the following forms:join(RemoteNode)
. Calling it is the same as calling
join(DefaultStoreId, RemoteNode)
where DefaultStoreId
is
returned by get_default_store_id/0
.join(RemoteMember)
. Calling it is the same as calling
join(StoreId, RemoteNode)
where StoreId
and RemoteNode
are
derived from RemoteMember
.See also: join/2.
join(RemoteNode::RemoteMember | RemoteNode | StoreId, Timeout::Timeout | RemoteNode) -> Ret
RemoteMember = ra:server_id()
RemoteNode = node()
StoreId = khepri:store_id()
Timeout = timeout()
Ret = ok | khepri:error()
Adds the local running Khepri store to a remote cluster.
This function accepts the following forms:join(RemoteNode, Timeout)
. Calling it is the same as calling
join(DefaultStoreId, RemoteNode, Timeout)
where DefaultStoreId
is returned by get_default_store_id/0
.join(StoreId, RemoteNode)
. Calling it is the same as calling
join(StoreId, RemoteNode, DefaultTimeout)
where DefaultTimeout
is
returned by khepri_app:get_default_timeout/0
.join(RemoteMember, Timeout)
. Calling it is the same as calling
join(StoreId, RemoteNode, Timeout)
where StoreId
and
RemoteNode
are derived from RemoteMember
.See also: join/3.
reset() -> Ret
Ret = ok | khepri:error()
Resets the store on this Erlang node.
reset(Timeout::StoreId | Timeout) -> Ret
StoreId = khepri:store_id()
Timeout = timeout()
Ret = ok | khepri:error()
Resets the store on this Erlang node.
reset(StoreId, Timeout) -> Ret
StoreId = khepri:store_id()
Timeout = timeout()
Ret = ok | khepri:error()
StoreId
: the name of the Khepri store.
Resets the store on this Erlang node.
It does that by force-deleting the Ra local server.
This function is also used to gracefully remove the local Khepri store node from a cluster.get_default_ra_system_or_data_dir() -> RaSystem | DataDir
RaSystem = atom()
DataDir = file:filename_all()
returns: the value of the default_ra_system
application environment
variable.
Returns the default Ra system name or data directory.
This is based on Khepri's default_ra_system` application environment
variable. The variable can be set to:
<ul>
<li>A directory (a string or binary) where data should be stored. A new Ra
system called `khepri` will be initialized with this directory.</li>
<li>A Ra system name (an atom). In this case, the user is expected to
configure and start the Ra system before starting Khepri.</li>
</ul>
If this application environment variable is unset, the default is to
configure a Ra system called `khepri
which will write data in
"khepri-$NODE"
in the current working directory where $NODE
is the
Erlang node name.
{khepri, [{default_ra_system, "/var/db/khepri"}]}.
get_default_store_id() -> StoreId
StoreId = khepri:store_id()
returns: the value of the default_store_id
application environment
variable.
Returns the default Khepri store ID.
This is based on Khepri'sdefault_store_id
application environment
variable. The variable can be set to an atom. The default is khepri
.
members() -> Ret
Ret = khepri:ok(Members) | khepri:error()
Members = [ra:server_id(), ...]
Returns the list of Ra members that are part of the cluster.
Calling this function is the same as callingmembers(StoreId)
with the
default store ID (see khepri_cluster:get_default_store_id/0
).
See also: members/1, members/2.
members(StoreId) -> Ret
StoreId = khepri:store_id()
Ret = khepri:ok(Members) | khepri:error()
Members = [ra:server_id(), ...]
Returns the list of Ra members that are part of the cluster.
Calling this function is the same as callingmembers(StoreId,
DefaultTimeout)
where DefaultTimeout
is returned by khepri_app:get_default_timeout/0
.
See also: members/2.
members(StoreId, Timeout) -> Ret
StoreId = khepri:store_id()
Timeout = timeout()
Ret = khepri:ok(Members) | khepri:error()
Members = [ra:server_id(), ...]
StoreId
: the ID of the store to stop.
Timeout
: the timeout.
returns: an {ok, Members}
tuple or an {error, Reason}
tuple. Members
is a non-empty list of Ra server IDs.
Returns the list of Ra members that are part of the cluster.
The Ra leader is queried for the list of members, therefore the membership view is consistent with the rest of the cluster.locally_known_members() -> Ret
Ret = khepri:ok(Members) | khepri:error()
Members = [ra:server_id(), ...]
Returns the list of Ra members that are part of the cluster.
Calling this function is the same as callinglocally_known_members(StoreId)
with the default store ID (see khepri_cluster:get_default_store_id/0
).
See also: locally_known_members/1, locally_known_members/2.
locally_known_members(StoreId) -> Ret
StoreId = khepri:store_id()
Ret = khepri:ok(Members) | khepri:error()
Members = [ra:server_id(), ...]
Returns the list of Ra members that are part of the cluster.
Calling this function is the same as callinglocally_known_members(StoreId, DefaultTimeout)
where DefaultTimeout
is
returned by khepri_app:get_default_timeout/0
.
See also: locally_known_members/2.
locally_known_members(StoreId, Timeout) -> Ret
StoreId = khepri:store_id()
Timeout = timeout()
Ret = khepri:ok(Members) | khepri:error()
Members = [ra:server_id(), ...]
StoreId
: the ID of the store to stop.
Timeout
: the timeout.
returns: an {ok, Members}
tuple or an {error, Reason}
tuple. Members
is a non-empty list of Ra server IDs.
Returns the list of Ra members that are part of the cluster.
The function queries a locally cached value first, then queries the local Ra server. Either way, the returned value may be out-of-date compared to the current membership known by the Ra leader.nodes() -> Ret
Ret = khepri:ok(Nodes) | khepri:error()
Nodes = [node(), ...]
Returns the list of Erlang nodes that are part of the cluster.
Calling this function is the same as callingnodes(StoreId)
with the
default store ID (see khepri_cluster:get_default_store_id/0
).
nodes(StoreId) -> Ret
StoreId = khepri:store_id()
Ret = khepri:ok(Nodes) | khepri:error()
Nodes = [node(), ...]
Returns the list of Erlang nodes that are part of the cluster.
Calling this function is the same as callingnodes(StoreId,
DefaultTimeout)
where DefaultTimeout
is returned by khepri_app:get_default_timeout/0
.
See also: nodes/2.
nodes(StoreId, Timeout) -> Ret
StoreId = khepri:store_id()
Timeout = timeout()
Ret = khepri:ok(Nodes) | khepri:error()
Nodes = [node(), ...]
Returns the list of Erlang nodes that are part of the cluster.
The Ra leader is queried for the list of members, therefore the membership view is consistent with the rest of the cluster.See also: members/2.
locally_known_nodes() -> Ret
Ret = khepri:ok(Nodes) | khepri:error()
Nodes = [node(), ...]
Returns the list of Erlang nodes that are part of the cluster.
Calling this function is the same as callinglocally_known_nodes(StoreId)
with the default store ID (see khepri_cluster:get_default_store_id/0
).
See also: locally_known_nodes/1, locally_known_nodes/2.
locally_known_nodes(StoreId) -> Ret
StoreId = khepri:store_id()
Ret = khepri:ok(Nodes) | khepri:error()
Nodes = [node(), ...]
Returns the list of Erlang nodes that are part of the cluster.
Calling this function is the same as callinglocally_known_nodes(StoreId,
DefaultTimeout)
where DefaultTimeout
is returned by khepri_app:get_default_timeout/0
.
See also: locally_known_nodes/2.
locally_known_nodes(StoreId, Timeout) -> Ret
StoreId = khepri:store_id()
Timeout = timeout()
Ret = khepri:ok(Nodes) | khepri:error()
Nodes = [node(), ...]
Returns the list of Erlang nodes that are part of the cluster.
The function queries a locally cached value first, then queries the local Ra server. Either way, the returned value may be out-of-date compared to the current membership known by the Ra leader.See also: locally_known_members/2.
wait_for_leader() -> Ret
Ret = ok | khepri:error()
Waits for a leader to be elected.
Calling this function is the same as callingwait_for_leader(StoreId)
with the default store ID (see khepri_cluster:get_default_store_id/0
).
See also: wait_for_leader/1, wait_for_leader/2.
wait_for_leader(StoreIdOrRaServer) -> Ret
StoreIdOrRaServer = StoreId | RaServer
StoreId = khepri:store_id()
RaServer = ra:server_id()
Ret = ok | khepri:error()
Waits for a leader to be elected.
Calling this function is the same as callingwait_for_leader(StoreId,
DefaultTimeout)
where DefaultTimeout
is returned by khepri_app:get_default_timeout/0
.
See also: wait_for_leader/2.
wait_for_leader(StoreIdOrRaServer, Timeout) -> Ret
StoreIdOrRaServer = StoreId | RaServer
StoreId = khepri:store_id()
RaServer = ra:server_id()
Timeout = timeout()
Ret = ok | khepri:error()
Timeout
: the timeout.
returns: ok
if a leader was elected or an {error, Reason}
tuple.
Waits for a leader to be elected.
This is useful if you want to be sure the clustered store is ready before issueing writes and queries. Note that there are obviously no guaranties that the Raft quorum will be lost just after this call.get_store_ids() -> [StoreId]
StoreId = khepri:store_id()
Returns the list of running stores.
is_store_running(StoreId) -> IsRunning
StoreId = khepri:store_id()
IsRunning = boolean()
Indicates if StoreId
is running or not.
Generated by EDoc