示例#1
0
        internal void Schedule(CommitID cID, ICommitable entry)
        {
            serialLock.AssertIsLockedByMe();
            if (state == State.Leader)
            {
                foreach (var l in log)
                {
                    if (l.Entry.CommitID == cID)
                    {
                        LogMinorEvent("Already in log: " + entry + ". Ignoring");
                        return;
                    }
                }

                LogMinorEvent("Issuing " + entry);
                PrivateEntry p = new PrivateEntry(new LogEntry(cID, currentTerm, entry));
                if (DebugState != null)
                {
                    DebugState.SignalSignalAppendAttempt(log.Count, p.Entry.Term);
                }

                if (CommitIndex == log.Count)
                {
                    lastCommit = DateTime.Now;
                }
                log.Add(p);                                  //add local
                Broadcast(new AppendEntries(this, p.Entry)); //transport remote

                ForeachConnection(c => c.ConsensusState.AppendTimeout = GetAppendMessageTimeout());

                ReCheckCommitment();
            }
            else
            {
                var cp = leader as Connection;
                if (cp != null)
                {
                    LogMinorEvent("Dispatching " + entry + " to " + leader);
                    cp.Dispatch(new CommitEntry(cID, currentTerm, entry));
                }
                else
                {
                    LogEvent("Received message out of consensus. Logging " + entry);
                    //dispatchQueue.Enqueue(Helper.Tuple(cID, entry));
                }
            }
        }
示例#2
0
 private void CommitTo(int newCommitCount)
 {
     serialLock.AssertIsLockedByMe();
     try
     {
         if (commitCount < newCommitCount)
         {
             lastCommit = DateTime.Now;
             LogMinorEvent("Committing " + commitCount + ".." + newCommitCount + ", history length " + log.Count);
             for (int i = commitCount; i < newCommitCount; i++)
             {
                 PrivateEntry e = log[i];
                 if (e == null)
                 {
                     LogMinorEvent("Skipping removed entry at #" + i);
                 }
                 else
                 {
                     if (DebugState != null)
                     {
                         DebugState.SignalExecution(i, e.Entry.Term, this);
                     }
                     if (!e.WasExecuted)
                     {
                         commitCount = Math.Max(commitCount, i + 1);
                         LogMinorEvent("Executing " + e.Entry);
                         e.Execute(this);
                         committed.TryRemove(e.Entry.CommitID);
                     }
                 }
             }
             //Debug.Assert(commitCount == newCommitCount);
             if (IsLeader)
             {
                 Broadcast(new AppendEntries(this));
                 nextActionAt = NextHeartbeat;
             }
         }
     }
     catch (Exception ex)
     {
     }
 }