public AppendEntriesResult AppendEntries(AppendEntriesCommand request) { lock (_lock) { _auditLog.LogRecord(new AuditRecord(AuditRecordType.RecAppendEntries, Id, _state, _currentTerm)); //this instance considers sender's Term to be stale - reject request and complete. //NOT IMPLEMENTED return false if log doesn't contain an entry. //NOT IMPLEMENTED if conflict, delete existing entry if (_currentTerm > request.Term) { _auditLog.LogRecord(new AuditRecord(AuditRecordType.RejectAppendEntries, Id, _state, _currentTerm)); return(new AppendEntriesResult { Term = _currentTerm, Success = false }); } //we should become a follower, irrespective of current state BecomeFollower(request.Term); return(new AppendEntriesResult { Term = _currentTerm, Success = true }); } }
private async Task SendHeartbeat() { List <IServerProxy> servers; AppendEntriesCommand heartBeatCmd; lock (_lock) { servers = new List <IServerProxy>(_servers); heartBeatCmd = new AppendEntriesCommand { Term = _currentTerm, LeaderId = Id }; } _auditLog.LogRecord(new AuditRecord(AuditRecordType.SendHeartbeat, Id, _state, _currentTerm)); while (_state == RaftServerState.Leader) { //TODO error handling, cancellation var pendingRequests = new List <Task>( servers.Select( s => SendAppendEntriesReceiveAck(s, heartBeatCmd) ) ); await _planner.HeatbeatDelay(); } }
public async Task <AppendEntriesResult> AppendEntries(AppendEntriesCommand request) { if (_config.Reachable(request.LeaderId, _proxy.Id)) { return(await _proxy.AppendEntries(request)); } throw new Exception("Network related exception"); }
public async Task <AppendEntriesResult> AppendEntries(AppendEntriesCommand request) { if (_rand.NextDouble() < _timeoutPct) { await Task.Delay(-1); } return(await _proxy.AppendEntries(request)); }
public async Task <AppendEntriesResult> AppendEntries(AppendEntriesCommand request) { if (_rand.NextDouble() < _exceptionPct) { throw new Exception("Network related exception"); } return(await _proxy.AppendEntries(request)); }
private async Task SendAppendEntriesReceiveAck(IServerProxy server, AppendEntriesCommand cmd) { try { var response = await server.AppendEntries(cmd); BecomeFollowerIfTermIsStale(response.Term); } catch (Exception) { //TODO exception logging to separate channel _auditLog.LogRecord(new AuditRecord(AuditRecordType.AppendEntriesRPCFailure, Id, _state, _currentTerm, $"RPC to: {server.Id}")); } }
public Task <AppendEntriesResult> AppendEntries(AppendEntriesCommand request) { return(Utility.AddLatency(_server.AppendEntries, request, _latency)); }