db-20 — Broader Ideas
The lab is deliberately small. Here is the menu of extensions that keep the same cross-language exam structure intact.
Elections
Add a term bump path. Replace fixed leader_idx = 0 with a leader
elected by randomised timeout (or a deterministic priority list, if
you want to keep cross-language byte identity). The snapshot already
serialises current_term, so the wire format does not need to
change. New invariant to test: after a leader change, every healthy
replica still converges to the same snapshot.
Linearizable reads
Currently reads are direct state_machine.get(k). To make them
linearizable, gate every read through a "read index" — leader confirms
it is still leader by exchanging heartbeats with a quorum, then
returns the value at commit_index. The byte-identity exam stays the
same; you add a TestReadIndexBlocksUntilQuorum-style scenario.
Log compaction / snapshot install
Today heal() ships the entire log. For long-running clusters that
is unbounded. Add Replica::compact(up_to_idx) that drops the prefix
and records a CompactedSnapshot at the head; change try_append to
also accept "follower has snapshot_idx == prev_idx - delta". The
exam scenarios still pass because the applied state is unchanged.
Multi-key transactions
Replace Op::Put with Op::Txn(Vec<KeyOp>) and apply atomically.
This is a small, well-scoped extension that nudges the lab toward
db-13 (transactions and MVCC) territory.
Membership changes
Add a JointConsensus op (Raft §6) that switches the cluster's
quorum during a configuration change. Trickier — the snapshot needs
to include the active config — but a worthy follow-on if you want to
see why "just add a node" is a real problem.
Disk persistence
Persist the log to a file (use db-01's pwrite-and-fsync pattern).
Test crash recovery by tearing down a replica and reconstructing it
from the log file. The snapshot bytes do not change.
Learner replicas
Add a replica role that receives entries but does not count toward quorum. Useful for read scaling. The snapshot bytes do not change.
Gossip-style membership
Replace the static replica list with a SWIM-style gossip layer that discovers and evicts replicas. Far more invasive — at this point you are building etcd.
Bridges to other labs in the repo
| Extension | Builds on which other lab? |
|---|---|
| Disk persistence | db-01 (storage primitives), db-03 (WAL) |
| Linearizable reads | db-16 (distributed fundamentals) |
| Multi-key transactions | db-13 (transactions and MVCC) |
| Compaction / snapshot | db-09 (leveldb), db-21 (storage advanced) |
| Real elections + RPCs | db-17 (raft) |
| Multi-region / quorum mix | db-22 (perf & benchmarking) |