Packages
cloister
0.12.3
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
retired
0.6.2
retired
0.6.1
retired
0.6.0
retired
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
The helper application to manage cluster, that uses hash ring to route requests to nodes. Automatically keeps track of connected nodes, provides helpers to determine where the term is to be executed, to multicast to all the nodes in the cluster and to retrieve current state of the cluster.
Current section
Files
Jump to
Current section
Files
lib/cloister.ex
defmodule Cloister do
@moduledoc ~s"""
`Cloister` is a consensus helper for clusters.
It is designed to be a configurable drop-in for transparent cluster support.
### Supported options
#{NimbleOptions.docs(Cloister.Options.schema())}
"""
use Boundary, exports: [Monitor, Node]
use DynamicSupervisor
@spec start_link(opts :: keyword()) :: Supervisor.on_start()
@doc false
def start_link(opts \\ []) do
{name, opts} = Keyword.pop(opts, :name, __MODULE__)
DynamicSupervisor.start_link(__MODULE__, opts, name: name)
end
@impl DynamicSupervisor
@doc false
def init(opts),
do: DynamicSupervisor.init(Keyword.merge([strategy: :one_for_one], opts))
@spec whois(group :: atom(), term :: any()) ::
node() | {:error, {:invalid_ring, :no_nodes}} | {:error, {:not_our_ring, atom()}}
@doc "Returns who would be chosen by a hash ring for the term in the group given"
def whois(group \\ nil, term),
do: with({:ok, node} <- Cloister.Modules.info_module().whois(group, term), do: node)
@spec mine?(term :: any()) :: boolean() | {:error, :no_such_ring}
@doc "Returns `true` if the hashring points to this node for the term given, `false` otherwise"
def mine?(term), do: whois(term) == node()
@spec multiapply(nil | [node()], module(), atom(), list()) :: any()
@doc """
Applies the function given as `m, f, a` on all the nodes given as a first parameter.
If no `nodes` are given, it defaults to `Cloister.siblings/0`.
"""
def multiapply(nodes \\ nil, m, f, a) do
nodes = if is_nil(nodes), do: Cloister.siblings(), else: nodes
:rpc.multicall(nodes, m, f, a)
end
@spec ring :: atom()
@doc "Returns the `ring` from current node cloister monitor state"
def ring, do: Cloister.Modules.info_module().ring()
defdelegate state, to: Cloister.Monitor
defdelegate siblings, to: Cloister.Monitor
defdelegate siblings!, to: Cloister.Monitor
defdelegate multicast(name, request), to: Cloister.Node
defdelegate multicall(name, request), to: Cloister.Node
defdelegate multicall(nodes, name, request), to: Cloister.Node
end