GizStack
View .mdOpen in ChatGPTOpen in Claude

gizfs:raft

A bounded durable Raft range. Network authentication, timeout scheduling and deterministic application of committed entries belong to the service. No local-clock lease is assumed.

gizlang
import * as Raft from "gizfs:raft";

Types

Limits

gizlang
type Limits = { entries: i64; bytes: i64; snapshotBytes: i64; }

The most entries and bytes that the log keeps before a snapshot, and the most bytes of a snapshot.

  • entries: i64
  • bytes: i64
  • snapshotBytes: i64

Entry

gizlang
type Entry = { index: i64; term: i64; kind: i64; data: bytes; voters: Vec<i64>; }

A log entry: its index and term, its kind (data or configuration), its data, and the voters that a configuration entry sets.

  • index: i64
  • term: i64
  • kind: i64
  • data: bytes
  • voters: Vec<i64>

Vote

gizlang
type Vote = { term: i64; candidate: i64; lastIndex: i64; lastTerm: i64; }

A request for a vote of a candidate, with the index and term of its last entry.

  • term: i64
  • candidate: i64
  • lastIndex: i64
  • lastTerm: i64

VoteReply

gizlang
type VoteReply = { term: i64; voter: i64; granted: bool; }

The answer of VOTER to a vote request.

  • term: i64
  • voter: i64
  • granted: bool

Append

gizlang
type Append = { term: i64; leader: i64; serial: i64; previous: i64; previousTerm: i64; entries: Vec<Entry>; commit: i64; round: i64; }

A request of the leader to append ENTRIES after the entry PREVIOUS of PREVIOUSTERM; it also carries the commit index.

  • term: i64
  • leader: i64
  • serial: i64
  • previous: i64
  • previousTerm: i64
  • entries: Vec<M40.Entry>
  • commit: i64
  • round: i64

AppendReply

gizlang
type AppendReply = { term: i64; follower: i64; serial: i64; accepted: bool; matched: i64; next: i64; round: i64; }

The answer of a follower to an append: whether it accepted, the index that it holds, and the next index to send.

  • term: i64
  • follower: i64
  • serial: i64
  • accepted: bool
  • matched: i64
  • next: i64
  • round: i64

Read

gizlang
type Read = { term: i64; index: i64; round: i64; }

A read barrier of the leader: its term, the commit index that the read waits for, and its round.

  • term: i64
  • index: i64
  • round: i64

Snapshot

gizlang
type Snapshot = { index: i64; term: i64; voters: Vec<i64>; data: bytes; }

A snapshot: the index and term of the last entry that it holds, its voters, and the state.

  • index: i64
  • term: i64
  • voters: Vec<i64>
  • data: bytes

Install

gizlang
type Install = { term: i64; leader: i64; serial: i64; snapshot: Snapshot; }

A request of the leader to install SNAPSHOT.

  • term: i64
  • leader: i64
  • serial: i64
  • snapshot: M40.Snapshot

InstallReply

gizlang
type InstallReply = { term: i64; follower: i64; serial: i64; index: i64; }

The answer of a follower to an install, with the index that it now holds.

  • term: i64
  • follower: i64
  • serial: i64
  • index: i64

Node

gizlang
type Node = { disk: Disk; id: i64; limits: Limits; term: i64; voted: i64; commit: i64; base: Snapshot; entries: Vec<Entry>; voters: Vec<i64>; joint: Vec<i64>; role: i64; stopped: bool; votes: Vec<i64>; peers: Vec<Progress>; serial: i64; round: i64; readCut: i64; readers: Vec<i64>; persistence: Persistence; ordered: () => Result<bool, string>; }

A Raft node: its durable log and state on its disk, its role, and the progress of its peers when it leads.

  • disk: M37.Disk
  • id: i64
  • limits: M40.Limits
  • term: i64
  • voted: i64
  • commit: i64
  • base: M40.Snapshot
  • entries: Vec<M40.Entry>
  • voters: Vec<i64>
  • joint: Vec<i64>
  • role: i64
  • stopped: bool
  • votes: Vec<i64>
  • peers: Vec<M40.Progress>
  • serial: i64
  • round: i64
  • readCut: i64
  • readers: Vec<i64>
  • persistence: M40.Persistence
  • ordered: () => _gizlang_sdk_core.Result<bool, string>

Functions

vote

gizlang
function vote(request: Vote): bytes

The encoding of REQUEST.

Effects: fail.

readVote

gizlang
function readVote(data: bytes): Result<Vote, string>

The vote request of DATA. It fails when the encoding is not valid.

Effects: fail, read, write, console, io.

voteReply

gizlang
function voteReply(reply: VoteReply): bytes

The encoding of REPLY.

Effects: fail.

readVoteReply

gizlang
function readVoteReply(data: bytes): Result<VoteReply, string>

The vote answer of DATA. It fails when the encoding is not valid.

Effects: fail, read, write, console, io.

append

gizlang
function append(request: Append): bytes

The encoding of REQUEST.

Effects: fail.

readAppend

gizlang
function readAppend(data: bytes): Result<Append, string>

The append request of DATA. It fails when the encoding is not valid.

Effects: fail, read, write, console, io.

appendReply

gizlang
function appendReply(reply: AppendReply): bytes

The encoding of REPLY.

Effects: fail.

readAppendReply

gizlang
function readAppendReply(data: bytes): Result<AppendReply, string>

The append answer of DATA. It fails when the encoding is not valid.

Effects: fail, read, write, console, io.

installReply

gizlang
function installReply(reply: InstallReply): bytes

The encoding of REPLY.

Effects: fail.

readInstallReply

gizlang
function readInstallReply(data: bytes): Result<InstallReply, string>

The install answer of DATA. It fails when the encoding is not valid.

Effects: fail, read, write, console, io.

formats

gizlang
function formats(): Vec<Codec.Format>

The on-disk formats of this module. A test opens a committed store sample of every version.

Effects: fail.

open

gizlang
function open(disk: Disk, id: i64, voters: Vec<i64>, limits: Limits): Result<Node, string>

Hard state references a log generation and an immutable semantic snapshot; the log is read to its last whole frame. Unpublished append tails are ignored and truncated before reuse.

Effects: fail, read, write, console, io.

Methods

Node.lastIndex

gizlang
function Node.lastIndex(self: Node): i64

The index of the last entry of the log.

Effects: fail.

Node.initializeRestore

gizlang
function Node.initializeRestore(self: mut Node, data: bytes, sourceTerm: i64): Result<bool, string>

Offline restore creates a fresh, empty authenticated range. Import bytes and validate its semantic snapshot first; never merge into existing history.

Effects: fail, read, write, console, io.

Node.termAt

gizlang
function Node.termAt(self: Node, index: i64): i64

The term of the entry at INDEX.

Effects: fail.

Node.member

gizlang
function Node.member(self: Node, id: i64): bool

Whether ID is a voter, in the current or the joint configuration.

Effects: fail.

Node.yieldLeadership

gizlang
function Node.yieldLeadership(self: mut Node): Result<bool, string>

The leader gives up its role in its term (a leadership transfer): it proposes nothing more, and a voter whose log holds all of it can win the next term.

Effects: fail, read, write, console, io.

Node.caughtUp

gizlang
function Node.caughtUp(self: Node, id: i64): bool

True when the leader knows that voter ID holds its whole log.

Effects: fail.

Node.campaign

gizlang
function Node.campaign(self: mut Node): Result<Vote, string>

Starts an election for the next term and votes for itself; the vote request to send to the peers.

Effects: fail, read, write, console, io.

Node.vote

gizlang
function Node.vote(self: mut Node, request: Vote): Result<VoteReply, string>

The answer to the vote request REQUEST; a vote is durable before it is given.

Effects: fail, read, write, console, io.

Node.recordVote

gizlang
function Node.recordVote(self: mut Node, reply: VoteReply): Result<bool, string>

Counts the answer REPLY; true when the node became the leader.

Effects: fail, read, write, console, io.

Node.propose

gizlang
function Node.propose(self: mut Node, data: bytes): Result<i64, string>

Appends DATA as a new entry of the leader; its index.

Effects: fail, read, write, console, io.

Node.proposeMany

gizlang
function Node.proposeMany(self: mut Node, data: Vec<bytes>): Result<Vec<i64>, string>

Proposes each of DATA in order (Node.extend): a sole voter commits all of them with one log sync.

Effects: fail, read, write, console, io.

Node.appendMany

gizlang
function Node.appendMany(self: mut Node, data: Vec<bytes>): Result<Vec<i64>, string>

As proposeMany, but a sole voter syncs and commits DATA at its next flush (Node.flush), not here: its owner may answer reads of the state before DATA while the log syncs.

Effects: fail, read, write, console, io.

Node.flush

gizlang
function Node.flush(self: mut Node): Result<bool, string>

Syncs the entries not yet durable. A leader calls it after it sends their appends, so its sync and the followers' run in parallel.

Effects: fail, read, write, console, io.

Node.request

gizlang
function Node.request(self: mut Node, peer: i64, batch: i64): Result<Append, string>

Learner peers can receive entries but never contribute a vote or quorum.

Effects: fail.

Node.append

gizlang
function Node.append(self: mut Node, request: Append): Result<AppendReply, string>

The answer to the append request REQUEST, after the entries are durable.

Effects: fail, read, write, console, io.

Node.ack

gizlang
function Node.ack(self: mut Node, reply: AppendReply): Result<bool, string>

Counts the answer REPLY of a follower and moves the commit index; true when it moved.

Effects: fail, read, write, console, io.

Node.beginRead

gizlang
function Node.beginRead(self: mut Node): Result<Read, string>

Starts a read barrier at the commit index. It fails unless the node leads with a committed entry of its term.

Effects: fail.

Node.readIndex

gizlang
function Node.readIndex(self: mut Node, token: Read): Result<i64, string>

Apply through the returned index before replying; tokens cannot be reused after a new round or term. Each read round requires fresh matching peer replies, never old matches.

Effects: fail.

Node.readReady

gizlang
function Node.readReady(self: Node): bool

Non-consuming readiness for a transport executor. It grants no cut and does not replace readIndex's exact term/round/token validation.

Effects: fail.

Node.beginJoint

gizlang
function Node.beginJoint(self: mut Node, voters: Vec<i64>): Result<i64, string>

Starts a change of the voters to VOTERS through a joint configuration; the index of its entry.

Effects: fail, read, write, console, io.

Node.finishJoint

gizlang
function Node.finishJoint(self: mut Node): Result<i64, string>

Ends the joint configuration: the new voters alone; the index of its entry.

Effects: fail, read, write, console, io.

Node.compact

gizlang
function Node.compact(self: mut Node, index: i64, data: bytes): Result<Snapshot, string>

Compact only a committed, stable-configuration cut; snapshots carry semantic state and its voters atomically. The application must supply the exact state at this cut.

Effects: fail, read, write, console, io.

Node.install

gizlang
function Node.install(self: mut Node, leader: i64, term: i64, snapshot: Snapshot): Result<bool, string>

Snapshot transfer must authenticate the elected leader, verify bytes, and apply this snapshot before serving. Old snapshots never overwrite a newer committed prefix.

Effects: fail, read, write, console, io.

Node.snapshotRequest

gizlang
function Node.snapshotRequest(self: mut Node, peer: i64, snapshot: Snapshot): Result<Install, string>

The returned snapshot and serial are one authenticated transfer; a receipt never counts toward a read barrier. Appends after installation establish fresh read authority.

Effects: fail.

Node.installed

gizlang
function Node.installed(self: mut Node, request: Install): Result<InstallReply, string>

Installs the snapshot of REQUEST; the answer to the leader.

Effects: fail, read, write, console, io.

Node.matchedOf

gizlang
function Node.matchedOf(self: Node, peer: i64): i64

The last index the leader knows PEER holds, or 0.

Effects: fail.

Node.ackSnapshot

gizlang
function Node.ackSnapshot(self: mut Node, reply: InstallReply): Result<bool, string>

Counts the answer REPLY to an install.

Effects: fail, read, write, console, io.

Node.committed

gizlang
function Node.committed(self: Node, after: i64): Result<Vec<Entry>, string>

A service may only apply entries at or below commit, in index order.

Effects: fail.