feat: add leadership transfer via TimeoutNow RPC (Gap 8.4)
- Add RaftTimeoutNowWire: 16-byte wire type [8:term][8:leaderId] with
Encode/Decode roundtrip, matching Go's sendTimeoutNow wire layout
- Add TimeoutNow(group) subject "$NRG.TN.{group}" to RaftSubjects
- Add SendTimeoutNowAsync to IRaftTransport; implement in both
InMemoryRaftTransport (synchronous delivery) and NatsRaftTransport
(publishes to $NRG.TN.{group})
- Add TransferLeadershipAsync(targetId, ct) to RaftNode: leader sends
TimeoutNow RPC, blocks proposals via _transferInProgress flag, polls
until target becomes leader or 2x election timeout elapses
- Add ReceiveTimeoutNow(term) to RaftNode: target immediately starts
election bypassing pre-vote, updates term if sender's term is higher
- Block ProposeAsync with InvalidOperationException during transfer
- 15 tests in RaftLeadershipTransferTests covering wire roundtrip,
ReceiveTimeoutNow behaviour, proposal blocking, target leadership,
timeout on unreachable peer, and transfer flag lifecycle
This commit is contained in:
@@ -198,4 +198,23 @@ public sealed class NatsRaftTransport : IRaftTransport
|
||||
var payload = System.Text.Encoding.UTF8.GetBytes(peer);
|
||||
_publish(removePeerSubject, null, payload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a TimeoutNow RPC to the target follower, asking it to immediately
|
||||
/// start an election to facilitate leadership transfer.
|
||||
///
|
||||
/// Publishes a <see cref="RaftTimeoutNowWire"/>-encoded payload to
|
||||
/// <c>$NRG.TN.{group}</c>. The target node's message handler decodes
|
||||
/// it and calls <see cref="RaftNode.ReceiveTimeoutNow"/>.
|
||||
///
|
||||
/// Go reference: raft.go sendTimeoutNow
|
||||
/// </summary>
|
||||
public Task SendTimeoutNowAsync(string leaderId, string targetId, ulong term, CancellationToken ct)
|
||||
{
|
||||
_ = targetId;
|
||||
var subject = RaftSubjects.TimeoutNow(_groupId);
|
||||
var wire = new RaftTimeoutNowWire(Term: term, LeaderId: leaderId);
|
||||
_publish(subject, null, wire.Encode());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user