feat(raft): add membership proposals, snapshot checkpoints, and log compaction (B4+B5+B6)
- ProposeAddPeerAsync/ProposeRemovePeerAsync: single-change-at-a-time membership changes through RAFT consensus (Go ref: raft.go:961-1019) - RaftLog.Compact: removes entries up to given index for log compaction - CreateSnapshotCheckpointAsync: creates snapshot and compacts log in one operation - DrainAndReplaySnapshotAsync: drains commit queue, installs snapshot, resets indices - Pre-vote protocol skipped (Go NATS doesn't implement it either) - 23 new tests in RaftMembershipAndSnapshotTests
This commit is contained in:
@@ -7,6 +7,11 @@ public sealed class RaftLog
|
||||
|
||||
public IReadOnlyList<RaftLogEntry> Entries => _entries;
|
||||
|
||||
/// <summary>
|
||||
/// The base index after compaction. Entries before this index have been removed.
|
||||
/// </summary>
|
||||
public long BaseIndex => _baseIndex;
|
||||
|
||||
public RaftLogEntry Append(int term, string command)
|
||||
{
|
||||
var entry = new RaftLogEntry(_baseIndex + _entries.Count + 1, term, command);
|
||||
@@ -28,6 +33,21 @@ public sealed class RaftLog
|
||||
_baseIndex = snapshot.LastIncludedIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all log entries with index <= upToIndex and advances the base index accordingly.
|
||||
/// This is log compaction: entries covered by a snapshot are discarded.
|
||||
/// Go reference: raft.go WAL compact / compactLog.
|
||||
/// </summary>
|
||||
public void Compact(long upToIndex)
|
||||
{
|
||||
var removeCount = _entries.Count(e => e.Index <= upToIndex);
|
||||
if (removeCount > 0)
|
||||
{
|
||||
_entries.RemoveRange(0, removeCount);
|
||||
_baseIndex = upToIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PersistAsync(string path, CancellationToken ct)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
||||
|
||||
Reference in New Issue
Block a user