public void Commit(Node node, CommitID myID) { Log.Message("GEC[" + EndedGeneration + "]"); var parent = node as Interface; if (EndedGeneration < parent.generation) { Log.Message("GEC ignored: " + parent.generation); return; } parent.gecCommits.Enqueue(new Tuple <CommitID, int>(myID, EndedGeneration)); CommitID flush = CommitID.None; Tuple <CommitID, int> check; while (parent.gecCommits.TryPeek(out check) && check.Item2 + 2 < EndedGeneration) { parent.gecCommits.TryDequeue(out check); if (check.Item2 + 2 < EndedGeneration) { flush = check.Item1; } } if (flush != CommitID.None) { Log.Minor("Collecting fossils from " + flush); parent.RemoveFossils(flush, true); } parent.generation = EndedGeneration + 1; Log.Message("OnGenerationEnd(" + EndedGeneration + ")"); parent.Notify.OnGenerationEnd(EndedGeneration); parent.Schedule(new TimeWindowReport(EndedGeneration, Clock.Now - TimeStamp)); }
/// <summary> /// Schedules removal of all committed log entries older than the specified commit. /// Nothing happens if the specified commit is not found at the time of execution. /// </summary> /// <param name="threshold">Commit to compare with</param> /// <param name="includeThreshold"></param> public CommitID RemoveFossils(CommitID threshold, bool includeThreshold) { if (threshold == CommitID.None) { return(CommitID.None); } return(Schedule(new FossilShredder(threshold, includeThreshold))); }
private int FindLogEntry(CommitID id) { //for (int i = log.Offset; i < log.Count; i++) for (int i = log.Count - 1; i >= log.Offset; i--) //better run backwards in case member has been rebooted and started with fresh commit ids { if (log[i].Entry.CommitID == id) { return(i); } } return(-1); }
/// <summary> /// Completely removes all currently logged/scheduled entries. /// The fossil remover itself cannot be removed /// </summary> /// <returns></returns> public CommitID RemoveFossils() { CommitID rs = CommitID.None; DoSerialized(() => { var cID = rs = new CommitID(MemberID.Identifier, commitSerial++); var e = new FossilShredder(cID, false); Schedule(cID, e); committed.GetOrAdd(cID, new Committed() { comm = e, lastAttempt = DateTime.Now }); }); return(rs); }
public void Commit(Node node, CommitID myID) { node.DoSerialized(() => { int cnt = node.FindLogEntry(threshold); node.LogMinorEvent("Attempting to clean log of length " + node.log.Count + ". Threshold found at " + cnt); if (includeThreshold) { cnt++; } if (cnt > 0) { node.log.SetOffset(cnt); } }); }
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)); } } }
/// <summary> /// Registers an object to be committed to the consensus. /// If a leader is currently known, the object is sent to the leader for logging. /// The leader executes the commit protocol on the new entry. /// If no leader is known, the message is queued for later delivery. /// </summary> /// <param name="entry">Object to commit. Null-objects are ignored. Type must be declared Serializable</param> public CommitID Schedule(ICommitable entry) { if (!Attribute.IsDefined(entry.GetType(), typeof(SerializableAttribute))) { throw new SerializationException("Entry " + entry + " is not marked serializable"); } CommitID rs = CommitID.None; if (entry == null) { return(rs); } DoSerialized(() => { var cID = rs = new CommitID(MemberID.Identifier, commitSerial++); Schedule(cID, entry); committed.GetOrAdd(cID, new Committed() { comm = entry, lastAttempt = DateTime.Now }); }); return(rs); }
public CommitEntry(CommitID c, int term, ICommitable e) : base(term) { this.e = e; this.c = c; }
public LogEntry(CommitID id, int term, ICommitable op) { CommitID = id; Term = term; Operation = op; }
public void Commit(Node node, CommitID myID) { var parent = node as Interface; parent.Notify.OnMessageCommit(confirmTo, msg); }
public void Commit(Node node, CommitID myID) { var parent = node as Interface; parent.timing.Include(EndedGeneration, parent.Configuration.Size, Delay); }
public FossilShredder(CommitID threshold, bool includeThreshold) { this.threshold = threshold; this.includeThreshold = includeThreshold; }
public void Commit(Node node, CommitID myID) { node.Join(NewCFG); }