예제 #1
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);
        }
예제 #2
0
 public void VerifyHeartBeatsMessages(IAsyncResult result)
 {
     try
     {
         if (changedState)
         {
             return;
         }
         RemoteAsyncCallAppendEntryDelegate del = (RemoteAsyncCallAppendEntryDelegate)((AsyncResult)result).AsyncDelegate;
         ResponseMessage r = del.EndInvoke(result);
         if (r.Term > this.term)
         {
             changedState = true;
             this.node.SetState(new Follower(this.node, r.Term, this.leaderLog.log));
         }
         this.leaderLog.FollowersCommitIndex[r.SharedId] = r.CommitIndex;
     }
     catch (Exception ex) {}
 }
예제 #3
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);
        }