Package-level declarations

Types

Link copied to clipboard
@Serializable
value class ClientId(val value: String)

Opaque, comparable client identity for Raft §8 client-serial dedup.

Link copied to clipboard

Thrown by a node using a caller-supplied durable ClientId when it observes another live writer committing under that same identity (Raft §8 collision). Indicates an operational error — two processes were handed one durable id. Fail loud; do not retry under the same id.

Link copied to clipboard
sealed interface ClientIdentity

How a RaftNode obtains its Raft §8 client identity for proposal dedup.

Link copied to clipboard

The authoritative client-serial dedup table for a consumer's state machine (Raft §8).

Link copied to clipboard
@Serializable
data class ClusterConfig(val voters: Set<NodeId>, val learners: Set<NodeId> = emptySet())

Describes the membership of a Raft cluster.

Link copied to clipboard
sealed interface Committed

One ordered instruction in the committed stream delivered to a consumer's state machine.

Link copied to clipboard
@Serializable
data class ConfigPayload(val old: ClusterConfig?, val new: ClusterConfig)

The membership payload carried by a config log entry (§6 joint consensus).

Link copied to clipboard
@Serializable
data class DedupKey(val clientId: ClientId, val requestId: Long)

A proposal's end-to-end dedup identity: a clientId plus a per-client monotonic requestId.

Link copied to clipboard

Why a candidate's RequestVote or PreVote was denied by the responding node.

Link copied to clipboard

An in-memory RaftStorage implementation.

Link copied to clipboard
class LeadershipLostException(message: String = "leadership lost while proposal was in flight") : Exception

Thrown by RaftNode.propose when this node loses leadership while waiting for the proposal to be committed by a quorum.

Link copied to clipboard

Why a leadership transfer was abandoned without completing.

Link copied to clipboard

Thrown by RaftNode.transferLeadership when the transfer could not complete.

Link copied to clipboard
@Serializable
data class LogEntry(val index: Long, val term: Long, val command: ByteArray, val isNoOp: Boolean = false, val config: ConfigPayload? = null, val dedupKey: DedupKey? = null)

One entry in the replicated Raft log.

Link copied to clipboard
class MembershipChangeInProgressException(message: String = "a membership change is already in progress — wait for it to commit before starting another") : Exception

Thrown by RaftNode.changeMembership when a membership change is already in progress (a config entry is uncommitted).

Link copied to clipboard
@Serializable
value class NodeId(val value: String)

A stable, unique identifier for a Raft cluster member.

Link copied to clipboard
class NotLeaderException(message: String = "not the current leader") : Exception

Thrown by RaftNode.propose when this node is not the current leader.

Link copied to clipboard
data class RaftConfig(val electionTimeoutMin: Duration = 150.milliseconds, val electionTimeoutMax: Duration = 300.milliseconds, val heartbeatInterval: Duration = 50.milliseconds, val strictTestGuard: Boolean = false, val expectVirtualTime: Boolean = false, val slowProposeThreshold: Duration = 100.milliseconds, val snapshotChunkCeiling: Int = 16 * 1024, val random: Random = Random.Default)

Tuning parameters for a Raft node's timing behaviour.

Link copied to clipboard
data class RaftEnvelope(val from: NodeId, val bytes: ByteArray)

A raw message from another cluster member, as received by the transport.

Link copied to clipboard
sealed interface RaftMetric

A structured metric event emitted by a RaftNode at key state-machine transitions.

Link copied to clipboard
interface RaftNode

The runtime interface for a single Raft cluster member.

Link copied to clipboard
sealed interface RaftRole

The role a node holds at a given instant in Raft's state machine.

Link copied to clipboard
interface RaftStorage

Durable state that a Raft node must persist to survive restarts.

Link copied to clipboard
sealed interface RaftTraceEvent

One engine state transition, emitted on RaftNode.trace.

Link copied to clipboard
interface RaftTransport

The messaging seam between the Raft engine and any underlying network layer.

Link copied to clipboard

Adapts a kuilt-core Seam to the RaftTransport interface.

Link copied to clipboard
class Snapshot(val throughIndex: Long, val state: ByteArray)

A state-machine snapshot. Opaque to kuilt-raft — it never deserializes state; only the consumer can collapse many log entries into compact state. The same payload flows both directions: the consumer publishes it via RaftNode.snapshots (outbound), and a lagging node receives it wrapped in Committed.Install (inbound).

Link copied to clipboard
data class SnapshotMeta(val lastIncludedIndex: Long, val lastIncludedTerm: Long, val config: ConfigPayload? = null)

Identifies the log position a snapshot covers: everything with index <= lastIncludedIndex.

Link copied to clipboard
Link copied to clipboard
class StoredSnapshot(val meta: SnapshotMeta, val state: ByteArray)

A persisted snapshot: its meta plus the opaque application state bytes.

Functions

Link copied to clipboard
suspend fun RaftNode.awaitRead(applied: StateFlow<Long>): Long

Linearizable read barrier: confirms the read index via RaftNode.readIndex, then suspends until applied reaches it, returning that index. applied is the caller's own monotonic applied-index flow, advanced as it consumes RaftNode.committed.

Link copied to clipboard
fun CoroutineScope.raftNode(clusterConfig: ClusterConfig, transport: RaftTransport, storage: RaftStorage, raftConfig: RaftConfig = RaftConfig(), identity: ClientIdentity = ClientIdentity.Auto, onMetric: (RaftMetric) -> Unit? = null): RaftNode

Creates and starts a RaftNode whose lifetime is tied to this CoroutineScope.