namespace NATS.Server.Raft; public interface IRaftTransport { Task> AppendEntriesAsync(string leaderId, IReadOnlyList followerIds, RaftLogEntry entry, CancellationToken ct); Task RequestVoteAsync(string candidateId, string voterId, VoteRequest request, CancellationToken ct); Task InstallSnapshotAsync(string leaderId, string followerId, RaftSnapshot snapshot, CancellationToken ct); } public sealed class InMemoryRaftTransport : IRaftTransport { private readonly Dictionary _nodes = new(StringComparer.Ordinal); public void Register(RaftNode node) { _nodes[node.Id] = node; } public Task> AppendEntriesAsync(string leaderId, IReadOnlyList followerIds, RaftLogEntry entry, CancellationToken ct) { var results = new List(followerIds.Count); foreach (var followerId in followerIds) { if (_nodes.TryGetValue(followerId, out var node)) { node.ReceiveReplicatedEntry(entry); results.Add(new AppendResult { FollowerId = followerId, Success = true }); } else { results.Add(new AppendResult { FollowerId = followerId, Success = false }); } } return Task.FromResult>(results); } public Task RequestVoteAsync(string candidateId, string voterId, VoteRequest request, CancellationToken ct) { if (_nodes.TryGetValue(voterId, out var node)) return Task.FromResult(node.GrantVote(request.Term, string.IsNullOrWhiteSpace(request.CandidateId) ? candidateId : request.CandidateId)); return Task.FromResult(new VoteResponse { Granted = false }); } public async Task InstallSnapshotAsync(string leaderId, string followerId, RaftSnapshot snapshot, CancellationToken ct) { _ = leaderId; if (_nodes.TryGetValue(followerId, out var node)) await node.InstallSnapshotAsync(snapshot, ct); } public async Task AppendHeartbeatAsync(string leaderId, IReadOnlyList followerIds, int term, CancellationToken ct) { _ = leaderId; foreach (var followerId in followerIds) { if (_nodes.TryGetValue(followerId, out var node)) node.ReceiveHeartbeat(term); } await Task.CompletedTask; } }