MIT · Deterministic replay

Raft without
the sockets

Schipper.Io.Raft is the consensus core IonStream does not have to reinvent. The host supplies IRaftTransport, IRaftLog, and optionally metrics and a clock. The node never reads DateTime.UtcNow except through those injections.

3+
Voters = Raft
1 / 2
Local / backup
CRC
Segment frames
1
Package dep

Paper Raft, plus the modes we actually run

One voter commits locally. Two voters are primary/backup. True Raft starts at three. Propose succeeds only after the entry is committed.

Voting majority

From three voters up, commit uses a voting-peer majority. Learners never stand in for a voter.

SegmentedRaftLog

CRC frames, idx sidecars, fsynced votes in meta.bin. Compact only whole prefix segments up to the safe index.

Injected clock

IRaftClock and a timeout draw make elections replayable. No Stopwatch in term transitions.

Log, transport, node.

The node does not open sockets. Your transport does. Addresses in peers are opaque strings.

C#
using var log = new SegmentedRaftLog(dataDir);
var node = new RaftNode(
    nodeId: "n1",
    peers: new Dictionary<string, string>
    {
        ["n2"] = "n2.internal:7000",
        ["n3"] = "n3.internal:7000",
    },
    transport, log, logger);

node.OnCommit += entry => { Apply(entry.Command.Span); return Task.CompletedTask; };
await node.StartAsync();

Source on GitHub

The only package reference is logging abstractions.

Repository