Beispiel #1
0
        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
                });
            }
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #3
0
 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");
 }
Beispiel #4
0
 public async Task <AppendEntriesResult> AppendEntries(AppendEntriesCommand request)
 {
     if (_rand.NextDouble() < _timeoutPct)
     {
         await Task.Delay(-1);
     }
     return(await _proxy.AppendEntries(request));
 }
Beispiel #5
0
 public async Task <AppendEntriesResult> AppendEntries(AppendEntriesCommand request)
 {
     if (_rand.NextDouble() < _exceptionPct)
     {
         throw new Exception("Network related exception");
     }
     return(await _proxy.AppendEntries(request));
 }
Beispiel #6
0
        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));
 }