aarondb/cluster_runtime
cluster_runtime — supervised, authenticated distributed-Erlang Raft runtime
A runtime actor stays local to preserve Gleam’s typed Subject capability.
A small Erlang mailbox gateway is registered for each node and forwards
validated wire tuples to that local actor. Remote clients therefore never
forge a Gleam subject from a PID; the gateway owns the raw-distribution edge
and re-wraps replies with the caller’s subject tag.
Types
pub type Config {
Config(
node: String,
cluster: String,
members: List(raft_runtime.Member),
trust: identity.TrustStore,
limits: identity.RpcLimits,
deadline_ms: Int,
)
}
Constructors
-
Config( node: String, cluster: String, members: List(raft_runtime.Member), trust: identity.TrustStore, limits: identity.RpcLimits, deadline_ms: Int, )
pub type Error {
InvalidConfiguration
RuntimeNotFound(String)
ProtocolMismatch(received: Int)
ClusterMismatch(received: String)
PeerRejected(identity.PeerError)
DeadlineExceeded
RemoteUnavailable(String)
ReplicationRejected(raft_runtime.Reply)
NotLeader(leader: option.Option(String))
Shutdown
}
Constructors
-
InvalidConfiguration -
RuntimeNotFound(String) -
ProtocolMismatch(received: Int) -
ClusterMismatch(received: String) -
PeerRejected(identity.PeerError) -
DeadlineExceeded -
RemoteUnavailable(String) -
ReplicationRejected(raft_runtime.Reply) -
NotLeader(leader: option.Option(String)) -
Shutdown
pub type Frame {
Frame(
version: Int,
cluster: String,
from: Peer,
bytes: Int,
rpc: raft_runtime.Rpc,
)
}
Constructors
-
Frame( version: Int, cluster: String, from: Peer, bytes: Int, rpc: raft_runtime.Rpc, )
pub type Message {
Receive(
Frame,
process.Subject(Result(raft_runtime.Reply, Error)),
)
Join(Peer, process.Subject(Result(Nil, Error)))
Elect(Int, process.Subject(Result(Nil, Error)))
Replicate(String, process.Subject(Result(Int, Error)))
Inspect(process.Subject(Snapshot))
Stop(process.Subject(Nil))
}
Constructors
-
Receive( Frame, process.Subject(Result(raft_runtime.Reply, Error)), ) -
Join(Peer, process.Subject(Result(Nil, Error))) -
Elect(Int, process.Subject(Result(Nil, Error))) -
Replicate(String, process.Subject(Result(Int, Error))) -
Inspect(process.Subject(Snapshot)) -
Stop(process.Subject(Nil))
pub type Peer {
Peer(node: String, fingerprint: String)
}
Constructors
-
Peer(node: String, fingerprint: String)
pub type Runtime =
process.Subject(Message)
pub type Snapshot {
Snapshot(
node: String,
raft: raft_runtime.State,
peers: List(Peer),
running: Bool,
)
}
Constructors
-
Snapshot( node: String, raft: raft_runtime.State, peers: List(Peer), running: Bool, )
Values
pub fn connect(
cluster: String,
node: String,
) -> Result(process.Subject(Message), Error)
pub fn elect(
runtime: process.Subject(Message),
granted_votes: Int,
deadline_ms: Int,
) -> Result(Nil, Error)
pub fn inspect(
runtime: process.Subject(Message),
deadline_ms: Int,
) -> Result(Snapshot, Error)
pub fn join(
runtime: process.Subject(Message),
peer: Peer,
deadline_ms: Int,
) -> Result(Nil, Error)
pub const protocol_version: Int
pub fn receive(
runtime: process.Subject(Message),
frame: Frame,
deadline_ms: Int,
) -> Result(raft_runtime.Reply, Error)
pub fn replicate(
runtime: process.Subject(Message),
command: String,
deadline_ms: Int,
) -> Result(Int, Error)
Appends locally then synchronously delivers authenticated AppendEntries to every joined peer. The caller gets success only after every joined peer reports the matching append; the consensus adapter later turns those acknowledgements into quorum commit evidence.
pub fn shutdown(
runtime: process.Subject(Message),
deadline_ms: Int,
) -> Result(Nil, Error)
pub fn start(
config: Config,
) -> Result(process.Subject(Message), Error)
pub fn supervised(
config: Config,
) -> supervision.ChildSpecification(process.Subject(Message))