feat: add randomized election timeout jitter (Gap 8.8)
Add RandomizedElectionTimeout() method to RaftNode returning TimeSpan in [ElectionTimeoutMinMs, ElectionTimeoutMaxMs) using TotalMilliseconds (not .Milliseconds component) to prevent synchronized elections after partitions. Make Random injectable for deterministic testing. Fix SendHeartbeatAsync stub in NatsRaftTransport and test-local transport implementations to satisfy the IRaftTransport interface added in Gap 8.7.
This commit is contained in:
@@ -217,4 +217,42 @@ public sealed class NatsRaftTransport : IRaftTransport
|
||||
_publish(subject, null, wire.Encode());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends heartbeat RPCs to all listed followers over NATS to confirm quorum for
|
||||
/// linearizable reads. Publishes an empty AppendEntry to each follower's heartbeat
|
||||
/// subject and invokes <paramref name="onAck"/> for each that is considered reachable
|
||||
/// (fire-and-forget in this transport; ACK is optimistic).
|
||||
///
|
||||
/// Go reference: raft.go — leader sends empty AppendEntries to confirm quorum for reads.
|
||||
/// </summary>
|
||||
public Task SendHeartbeatAsync(
|
||||
string leaderId,
|
||||
IReadOnlyList<string> followerIds,
|
||||
int term,
|
||||
Action<string> onAck,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var appendSubject = RaftSubjects.AppendEntry(_groupId);
|
||||
|
||||
foreach (var followerId in followerIds)
|
||||
{
|
||||
// Encode a heartbeat as an empty AppendEntry (no log entries).
|
||||
var wire = new RaftAppendEntryWire(
|
||||
LeaderId: leaderId,
|
||||
Term: (ulong)term,
|
||||
Commit: 0,
|
||||
PrevTerm: 0,
|
||||
PrevIndex: 0,
|
||||
Entries: [],
|
||||
LeaderTerm: (ulong)term);
|
||||
|
||||
_publish(appendSubject, null, wire.Encode());
|
||||
|
||||
// Optimistically acknowledge — a full implementation would await replies.
|
||||
onAck(followerId);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user