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.
One voter commits locally. Two voters are primary/backup. True Raft starts at three. Propose succeeds only after the entry is committed.
From three voters up, commit uses a voting-peer majority. Learners never stand in for a voter.
CRC frames, idx sidecars, fsynced votes in meta.bin. Compact only whole prefix segments up to the safe index.
IRaftClock and a timeout draw make elections replayable. No Stopwatch in term transitions.
The node does not open sockets. Your transport does. Addresses in peers are opaque strings.
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();