DurableStoreRaftStorage

A RaftStorage that keeps a node's term, vote, established leader, log and snapshot in a DurableStore, so they are all still there after the process restarts.

This is the reference durable adapter — the answer to the "inject a persistent RaftStorage in production" line every other doc in this module points at. Give it whichever DurableStore the platform provides (FileChannelDurableStore on JVM/Android, NSFileManagerDurableStore on iOS/macOS, IndexedDbDurableStore in a browser) and the node comes back holding what it knew:

val storage = DurableStoreRaftStorage.open(FileChannelDurableStore(nodeDirectory))
val node = scope.raftNode(cluster, transport, storage)

Samples

// One store per node. In production this is the platform's crash-safe implementation —
// FileChannelDurableStore(nodeDirectory), NSFileManagerDurableStore(nodeDirectory), or
// IndexedDbDurableStore.open(nodeDatabase). A sample uses the in-memory one.
val store: DurableStore = InMemoryDurableStore()

val storage = DurableStoreRaftStorage.open(store)

// Every mutator commits to the medium before it updates its own memory, so a term that has
// been saved is a term that survives — pass this to `scope.raftNode(cluster, transport, storage)`.
storage.saveTermAndVotedFor(term = 4L, votedFor = NodeId("node-a"))
storage.appendEntries(listOf(LogEntry(index = 1L, term = 4L, command = byteArrayOf(7, 8, 9))))

// A restart: a second handle onto the same store, decoding what the first one wrote.
val restarted = DurableStoreRaftStorage.open(store)
check(restarted.term() == 4L)
check(restarted.votedFor() == NodeId("node-a"))
check(restarted.entries().single().command.contentEquals(byteArrayOf(7, 8, 9)))

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
open suspend override fun appendEntries(entries: List<LogEntry>)

Appends entries to the end of the persistent log.

Link copied to clipboard
open suspend override fun discardLogPrefix(throughIndex: Long)

Removes all log entries with index <= throughIndex. Idempotent; tolerates a floor below the first retained entry.

Link copied to clipboard
open suspend override fun entries(fromIndex: Long = 0): List<LogEntry>

Returns all log entries with index >= fromIndex.

Link copied to clipboard
open suspend override fun leaderForTerm(): LeaderForTerm?

Returns the leader this node established for some term, or null if it has never established one. See saveLeaderForTerm.

Link copied to clipboard
open suspend override fun loadSnapshot(): StoredSnapshot?

Returns the stored snapshot, or null if none has been saved.

Link copied to clipboard
open suspend override fun saveLeaderForTerm(term: Long, leaderId: NodeId)

Persists leaderId as the node §5.2 established as leader of term, replacing any previously stored record.

Link copied to clipboard
open suspend override fun saveSnapshot(meta: SnapshotMeta, state: ByteArray)

Persists state as the snapshot covering all entries with index <= meta.lastIncludedIndex.

Link copied to clipboard
open suspend override fun saveTerm(term: Long)

Persists term as the latest observed term.

Link copied to clipboard
open suspend override fun saveTermAndVotedFor(term: Long, votedFor: NodeId?)

Atomically persists term and votedFor in a single durable write.

Link copied to clipboard
open suspend override fun saveVotedFor(nodeId: NodeId?)

Persists nodeId as the node voted for in the current term.

Link copied to clipboard
open suspend override fun term(): Long

Returns the latest term this node has observed.

Link copied to clipboard
open suspend override fun truncateFrom(index: Long)

Removes all log entries with index >= [index].

Link copied to clipboard
open suspend override fun votedFor(): NodeId?

Returns the NodeId this node voted for in the current term, or null if it has not yet voted.