aarondb/consensus
consensus — leader-gated command and lease reference surface
This module composes committed Raft positions with the deterministic command state machine. It is deliberately transport-free: callers supply quorum evidence and a monotonic clock reading. No wall-clock conversion is trusted.
Types
pub type Lease {
Lease(
resource: String,
holder: String,
fence: Int,
expires_at: Int,
)
}
Constructors
-
Lease( resource: String, holder: String, fence: Int, expires_at: Int, )
pub type LeaseCommand {
Acquire(resource: String, holder: String, ttl: Int)
Renew(resource: String, holder: String, fence: Int, ttl: Int)
Revoke(resource: String, holder: String, fence: Int)
}
Constructors
-
Acquire(resource: String, holder: String, ttl: Int) -
Renew(resource: String, holder: String, fence: Int, ttl: Int) -
Revoke(resource: String, holder: String, fence: Int)
pub type ReadError {
ReadRedirect(leader: option.Option(String))
ReadQuorumUnavailable
ReadIndexUnavailable
}
Constructors
-
ReadRedirect(leader: option.Option(String)) -
ReadQuorumUnavailable -
ReadIndexUnavailable
pub type State {
State(
raft: raft_runtime.State,
commands: command.State,
leases: List(Lease),
last_now: Int,
)
}
Constructors
-
State( raft: raft_runtime.State, commands: command.State, leases: List(Lease), last_now: Int, )
pub type SubmitError {
Redirect(leader: option.Option(String))
QuorumUnavailable
NotCommitted
CommandFailed(error: command.CommandError)
InvalidClock(now: Int, last_now: Int)
InvalidTtl
LeaseHeld(resource: String, fence: Int, expires_at: Int)
StaleFence(resource: String, expected: Int, received: Int)
LeaseHolderMismatch(resource: String)
}
Constructors
-
Redirect(leader: option.Option(String)) -
QuorumUnavailable -
NotCommitted -
CommandFailed(error: command.CommandError) -
InvalidClock(now: Int, last_now: Int) -
InvalidTtl -
LeaseHeld(resource: String, fence: Int, expires_at: Int) -
StaleFence(resource: String, expected: Int, received: Int) -
LeaseHolderMismatch(resource: String)
Values
pub fn lease(
state: State,
index: Int,
replicated: Int,
now: Int,
request: LeaseCommand,
) -> Result(#(State, option.Option(Lease)), SubmitError)
Uses a caller-supplied monotonic time domain. Regressing clock values are rejected, so expiry cannot be extended by a local wall-clock rollback.
pub fn linearizable_read(
state: State,
read_index: Int,
quorum_confirmed: Bool,
key: String,
) -> Result(option.Option(String), ReadError)
Linearizable reads require leader confirmation and a ReadIndex at least as recent as the command state. LeaseRead is intentionally not provided here: callers must use a validated lease instead of relabelling a local read.
pub fn new(raft_state: raft_runtime.State) -> State
pub fn submit(
state: State,
index: Int,
replicated: Int,
request: command.CommandRequest,
) -> Result(#(State, command.CommandResult), SubmitError)
Submission is accepted only on the elected leader after current-term quorum replication has committed the supplied index.
pub fn validate_fence(
state: State,
resource: String,
fence: Int,
) -> Result(Nil, SubmitError)