Пример #1
0
        public ResponseMessage AppendEntry(AppendEntriesMessage message)
        {
            try
            {
                TimerHelper.PauseTimer(ElectionTimer);
                //1.Reply false if term < currentTerm
                if (message.Term < this.term)
                {
                    return(new ResponseMessage(this.term, false, message.SharedId, this.FollowerLog.CommitIndex));
                }
                this.term = message.Term;
                try
                {
                    this.FollowerLog.AppendNewEntries(message.Entry);
                }
                catch (Exception ex) {}

                leaderUrl = message.url;
                //Restart timer to a new random value
                TimerHelper.RestartTimer(GetElectionTimeout(), ElectionTimer);

                return(new ResponseMessage(this.term, true, message.SharedId, this.FollowerLog.CommitIndex));
            }
            catch (Exception ec) {}
            return(new ResponseMessage(this.term, true, message.SharedId, this.FollowerLog.CommitIndex));
        }
Пример #2
0
        public ResponseMessage AppendEntry(AppendEntriesMessage message)
        {
            CheckFreeze();

            bool shouldBecomeFollower = false;

            TimerHelper.PauseTimer(HeartBeatTimer);
            if ((message.Term < this.term) ||
                !(this.leaderLog.Match(message.PreviousLogIndex, message.PreviousLogTerm)))
            {
                TimerHelper.StartTimer(HeartBeatTimer);
                return(new ResponseMessage(this.term, false, message.SharedId));
            }
            else if (message.Term > this.term)
            {
                this.term            = message.Term;
                shouldBecomeFollower = true;
            }
            leaderLog.AppendNewEntries(message.Entry);

            leaderLog.UpdateCommitIndex(message.LeaderCommit);

            if (shouldBecomeFollower)
            {
                node.SetState(new Follower(node, this.term, this.leaderLog));
            }

            return(new ResponseMessage(this.term, true, message.SharedId));
        }
Пример #3
0
        public ResponseMessage AppendEntry(AppendEntriesMessage message)
        {
            CheckFreeze();
            if (message.Term < this.term)
            {
                return(new ResponseMessage(this.term, false, message.SharedId));
            }
            this.term = message.Term;

            if (message.LeaderCommit < this.CandidateLog.CommitIndex)
            {
                return(new ResponseMessage(this.term, false, message.SharedId, this.CandidateLog.CommitIndex));
            }
            try
            {
                this.CandidateLog.AppendNewEntries(message.Entry);
            }
            catch (Exception ex) {
            }

            leaderFound = true;
            TimerHelper.StopTimer(ElectionTimer);
            TimerHelper.StopTimer(RequestVotesTimer);
            this.node.SetState(new Follower(this.node, this.term, this.CandidateLog, this.votedFor));

            return(new ResponseMessage(this.term, true, message.SharedId, this.CandidateLog.CommitIndex));
        }
Пример #4
0
        private IAsyncResult RemoteAsyncCallAppendEntry(Node otherNode, AppendEntriesMessage message)
        {
            RemoteAsyncCallAppendEntryDelegate RemoteDel = new RemoteAsyncCallAppendEntryDelegate(otherNode.AppendEntry);
            AsyncCallback callback = new AsyncCallback(VerifyHeartBeatsMessages);
            IAsyncResult  RemAr    = RemoteDel.BeginInvoke(message, callback, null);

            return(RemAr);
        }
Пример #5
0
 public ResponseMessage AppendEntry(AppendEntriesMessage message)
 {
     throw new NotImplementedException();
 }
Пример #6
0
        public ITuple Take(ISchema schema)
        {
            ITuple result;

            Console.WriteLine("start take");
            result = this.node.TupleSpace.Take(schema);
            Console.WriteLine("end take");
            List <Entry> l;

            lock (this.leaderLog)
            {
                l = new List <Entry>();
                l.Add(new Entry("take", schema, this.term, this.leaderLog.CommitIndex));
                this.leaderLog.CommitIndex++;
                this.leaderLog.AppendNewEntries(l);
            }
            if (DF.N == 1)
            {
                return(result);
            }

            bool allAck    = false;
            int  consensus = 0;
            Dictionary <int, bool> alreadyTried = new Dictionary <int, bool>(DF.N);

            for (int i = 0; i < DF.N; i++)
            {
                alreadyTried[i] = false;
            }
            while (!allAck)
            {
                List <IAsyncResult> results = new List <IAsyncResult>();
                List <WaitHandle>   waits   = new List <WaitHandle>();
                //foreach (Node node in this.node.otherNodes)


                View         v = this.node.manager.RequestView();
                List <Entry> a = new List <Entry>();
                a.Add(new Entry("take", schema, this.term, this.leaderLog.CommitIndex));
                //foreach (KeyValuePair<int, Node> entry in nodesLeftToTry)
                foreach (KeyValuePair <int, Pingable> entry in v.pingables)
                {
                    if (!alreadyTried[entry.Key])
                    {
                        AppendEntriesMessage message = new AppendEntriesMessage(this.term, 0, 0, this.leaderLog.CommitIndex, l, entry.Key, node.url);
                        RemoteAsyncCallAppendEntryDelegate RemoteDel = new RemoteAsyncCallAppendEntryDelegate(node.otherNodes[entry.Key].AppendEntry);
                        IAsyncResult RemAr = RemoteDel.BeginInvoke(message, null, null);
                        results.Add(RemAr);
                        waits.Add(RemAr.AsyncWaitHandle);
                    }
                }

                allAck = WaitHandle.WaitAll(waits.ToArray(), DF.TIMEOUT);//Change to a more reliable value because of timeouts
                if (!allAck)
                {
                    //                   foreach(WaitHandle h in waits)
                    for (int i = 0; i < waits.Count; i++)
                    {
                        try
                        {
                            if (waits[i].WaitOne(0))
                            {
                                RemoteAsyncCallAppendEntryDelegate d = (RemoteAsyncCallAppendEntryDelegate)((AsyncResult)results[i]).AsyncDelegate;
                                ResponseMessage r = d.EndInvoke(results[i]);
                                if (r.Success && !alreadyTried[r.SharedId])
                                {
                                    //leaderLog.FollowersCommitIndex[r.SharedId]++;
                                    alreadyTried[r.SharedId] = true;
                                    consensus++;
                                }
                            }
                        }
                        catch (Exception ex) { }
                        if (consensus > DF.N / 2)
                        {
                            allAck = true;
                        }
                    }
                }
            }

            foreach (KeyValuePair <int, bool> entry in alreadyTried)
            {
                if (entry.Value)
                {
                    //leaderLog.FollowersCommitIndex[entry.Key]++;
                }
            }
            return(result);
        }