feat(raft): add commit queue, election timers, and peer health tracking (B1+B2+B3)
- CommitQueue<T>: channel-based queue for committed entries awaiting state machine application - RaftPeerState: tracks replication and health state (nextIndex, matchIndex, lastContact) - RaftNode: CommitIndex/ProcessedIndex tracking, election timer with randomized 150-300ms interval, peer state integration with heartbeat and replication updates - 52 new tests across RaftApplyQueueTests, RaftElectionTimerTests, RaftHealthTests
This commit is contained in:
46
src/NATS.Server/Raft/RaftPeerState.cs
Normal file
46
src/NATS.Server/Raft/RaftPeerState.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
namespace NATS.Server.Raft;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks replication and health state for a single RAFT peer.
|
||||
/// Go reference: raft.go peer tracking fields (nextIndex, matchIndex, last contact).
|
||||
/// </summary>
|
||||
public sealed class RaftPeerState
|
||||
{
|
||||
/// <summary>
|
||||
/// The peer's unique node identifier.
|
||||
/// </summary>
|
||||
public required string PeerId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The next log index to send to this peer (leader use only).
|
||||
/// </summary>
|
||||
public long NextIndex { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The highest log index known to be replicated on this peer.
|
||||
/// </summary>
|
||||
public long MatchIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp of the last successful communication with this peer.
|
||||
/// </summary>
|
||||
public DateTime LastContact { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this peer is considered active in the cluster.
|
||||
/// </summary>
|
||||
public bool Active { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this peer has been contacted within the election timeout window.
|
||||
/// Go reference: raft.go isCurrent check.
|
||||
/// </summary>
|
||||
public bool IsCurrent(TimeSpan electionTimeout)
|
||||
=> DateTime.UtcNow - LastContact < electionTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this peer is both active and has been contacted within the health threshold.
|
||||
/// </summary>
|
||||
public bool IsHealthy(TimeSpan healthThreshold)
|
||||
=> Active && DateTime.UtcNow - LastContact < healthThreshold;
|
||||
}
|
||||
Reference in New Issue
Block a user