Step 01 — Cluster and Replica

Goal: in ~30 minutes, build a single-replica Cluster::new(1) that accepts Put / Del and returns a state machine you can inspect.

What to read first

  • CONCEPTS.md § "Data model" and § "Propose / commit cycle".
  • db-17-raft/CONCEPTS.md for the words log entry, commit index, quorum if they are not yet second nature.

Concrete tasks

  1. Define OpKind, Op, LogEntry, Replica, Cluster in the language of your choice. Match the field layout from src/rust/src/lib.rs.
  2. Implement Replica::last_idx, Replica::try_append, Replica::advance_commit_to. Note that apply(state_machine, op) is the only place where state_machine mutates outside of truncate_and_replay.
  3. Implement Cluster::new(n), quorum, propose. For now, treat every reachable follower as a successful append (no NACK path yet).

Definition of done

#![allow(unused)]
fn main() {
let mut c = Cluster::new(1);
assert!(c.propose(Op::Put("a".into(), vec![1,2,3])));
assert_eq!(c.leader().state_machine.get("a"), Some(&vec![1,2,3]));
}

equivalents pass in Go and C++. Run cargo test single_replica_put_commits to confirm.

Common bugs at this stage

  • Forgetting to bump next_log_idx so two proposals get the same idx.
  • Applying op before the entry is committed.
  • Iterating an unsorted map somewhere (Go) — even at this stage, start the habit of sort.Strings(keys) before any deterministic output.