Beispiel #1
0
 private void BecomeLeader()
 {
     lock (_lock)
     {
         CancelScheduledEvents();
         _state = RaftServerState.Leader;
         _auditLog.LogRecord(new AuditRecord(AuditRecordType.BecomeLeader, Id, _state, _currentTerm));
         Task.Run(SendHeartbeat);
     }
 }
Beispiel #2
0
        public AuditRecord(AuditRecordType type, string candidate, RaftServerState state, int term, string extraInfo = "")
        {
            When = DateTime.Now;

            Type      = type;
            Id        = candidate;
            Term      = term;
            ExtraInfo = extraInfo;
            State     = state;

            Log.Write(GetLogEventLevel(type), "Raft audit: {@item}", this);
        }
Beispiel #3
0
        public Task BecomeFollower(int term)
        {
            lock (_lock)
            {
                CancelScheduledEvents();
                UpdateTerm(term);

                //Become follower can be called when we already are one (e.g. on receipt of a heartbeat)
                if (_state != RaftServerState.Follower)
                {
                    _state = RaftServerState.Follower;
                    _auditLog.LogRecord(new AuditRecord(AuditRecordType.BecomeFollower, Id, _state, _currentTerm));
                }
                return(Task.Run(ScheduleFollowerTimeout));
            }
        }
Beispiel #4
0
        public async Task BecomeCandidate()
        {
            _state = RaftServerState.Candidate;
            _auditLog.LogRecord(new AuditRecord(AuditRecordType.BecomeCandidate, Id, _state, _currentTerm));

            while (_state == RaftServerState.Candidate)
            {
                lock (_lock)
                {
                    CancelScheduledEvents();
                    _currentTerm++;
                    _votesReceived = 0;
                    _votedFor      = null;
                    _auditLog.LogRecord(new AuditRecord(AuditRecordType.StartElection, Id, _state, _currentTerm));

                    //vote for self
                    ReceiveVote(
                        new RequestVoteResult {
                        Term        = _currentTerm,
                        VoteGranted = true,
                        VoterId     = Id,
                    }

                        );
                    _votedFor = Id;

                    var token = _taskCancellation.Token;

                    //TODO error handling, cancellation
                    var pendingRequests = new List <Task>(
                        _servers.Select(
                            s => RequestAndReceiveVote(s, token)
                            )
                        );
                }
                //wait timeout period
                await _planner.ElectionDelay();

                //if we are still in candidate state, run another election
                //no need to cancel inflight vote requests because increment to term means they will be ignored
            }
        }