A cluster of BEAM nodes over Partisan, without Distributed Erlang.
:ok =
Sovite.Cluster.start(
name: :"mx1@10.0.0.1",
ip: {10, 0, 0, 1},
port: 4370,
tls: [cert_file: "node.pem", key_file: "node.key", ca_file: "cluster-ca.pem"]
)
{:ok, peer} = Sovite.Cluster.Peer.parse("mx2@10.0.0.2:4370")
:ok = Sovite.Cluster.join(peer)
Sovite.Cluster.send(:"mx2@10.0.0.2", MyApp.Server, {:hello, Sovite.Cluster.node()})Every node is connected to every other one (Partisan's full mesh
manager), over TLS 1.3 with mutual authentication: a node accepts
only peers whose certificate the cluster CA (:ca_file) signed, and
presents its own. There is no plaintext mode. Peers can send any
message to any registered process, so the cluster CA must sign the
certificates of cluster nodes and nothing else, and the peer port
should still only be reachable from the other nodes.
Partisan is one per VM: start/1 configures and starts the
:partisan application, and only one cluster runs at a time.
Messages go to processes registered by name on the other node (see
send/4); they are delivered as sent, and like Erlang messages, they
can be lost when a connection drops. call/4 waits for a reply that
the receiving process sends with reply/2. monitor_nodes/1
subscribes to {:nodeup, node} and {:nodedown, node} messages.
Sovite.Cluster.Joiner keeps joining a list of known peers.
Messages are on two channels: :control, for small messages, and
:bulk (send/4 with channel: :bulk), for large ones such as
message files, so they do not hold up the others.
Summary
Functions
Sends request to the process registered as name on node, and
waits for its reply. The process gets {:"$cluster_call", from, request}, and answers with reply/2.
The other members this node is connected to.
Whether this node is connected to node.
Joins the cluster peer is in.
Removes node from the cluster, or this node when node is this
node: its peers forget it, and it forgets them.
The members of the cluster, this node included, whether connected or not.
Subscribes the calling process to {:nodeup, node} and {:nodedown, node} messages, or unsubscribes it.
This node's name.
Answers a call/4.
Sends message to the process registered as name on node.
Returns {:error, reason} when it could not be handed to a
connection, mostly because node is not connected.
Configures and starts Partisan.
Whether Partisan runs.
Stops Partisan. Not from a process that an application stop is waiting for.
Types
@opaque from()
A request's sender, for reply/2.
Functions
Sends request to the process registered as name on node, and
waits for its reply. The process gets {:"$cluster_call", from, request}, and answers with reply/2.
Returns {:ok, reply}, or {:error, :timeout}, or {:error, reason}
when the request could not be sent. A reply that comes after the
timeout stays in the caller's mailbox as {:"$cluster_reply", tag, reply}. Takes the options of send/4.
@spec connected() :: [node()]
The other members this node is connected to.
Whether this node is connected to node.
@spec join(Sovite.Cluster.Peer.t()) :: :ok | {:error, term()}
Joins the cluster peer is in.
Removes node from the cluster, or this node when node is this
node: its peers forget it, and it forgets them.
@spec members() :: [node()]
The members of the cluster, this node included, whether connected or not.
Subscribes the calling process to {:nodeup, node} and {:nodedown, node} messages, or unsubscribes it.
@spec node() :: node()
This node's name.
Answers a call/4.
Sends message to the process registered as name on node.
Returns {:error, reason} when it could not be handed to a
connection, mostly because node is not connected.
Options
:channel-:control(the default) or:bulk, for large messages.
Configures and starts Partisan.
Options
:name- the node's name, an atom such as:"mx1@10.0.0.1". Required.:ip- the address to accept peers on. Required.:port- the port to accept peers on. Required.:tls-:cert_fileand:key_file, the node's certificate and key, and:ca_file, the cluster CA. Required.:max_message_size- the largest message, in bytes, a peer may send. Defaults to 64 MB.
Returns {:error, :already_started} if Partisan runs already.
@spec started?() :: boolean()
Whether Partisan runs.
@spec stop() :: :ok
Stops Partisan. Not from a process that an application stop is waiting for.