public virtual VectorClockSyncResult <T> Acknowledge(VectorClockNode <T> vectorClock) { vectorClock = NormalizeVectors(vectorClock); VectorClockNode <T> winner = this.IsDescendantOf(vectorClock) ? this : vectorClock.IsDescendantOf(this) ? vectorClock : null; if (winner != null) { Payload = winner.Payload; foreach (var version in Revision) { while (version.Version < winner.VersionOf(version.NodeID)) { version.Increment(); } } latestSyncResult = VectorClockSyncResult <T> .Successfull(this, winner); return(latestSyncResult); } latestSyncResult = VectorClockSyncResult <T> .Conflictual(this, new VectorClockConflict <T>(this, vectorClock)); return(latestSyncResult); }
private void TryToAknowledgeOthers(VectorClockNode <T> head) { foreach (var node in nodeMesh) { node.Value.Acknowledge(head); } }
private void ChewRequestQueue() { VectorClockNode <T> queueHead; if (!syncRequestQueue.TryDequeue(out queueHead)) { return; } Head = Head ?? queueHead; VectorClockSyncResult <T> syncResult = Head.Acknowledge(queueHead); if (syncResult.IsSuccessfull) { Head = syncResult.Solution; TryToAknowledgeOthers(Head); return; } syncResult = conflictResolver.ResolveConflict(syncResult); if (syncResult.IsSuccessfull) { Head = syncResult.Solution; TryToAknowledgeOthers(Head); return; } //Delegate conflict to node nodeMesh[queueHead.NodeID].Acknowledge(Head); //TryToAknowledgeOthers(Head); }
private VectorClockNode <T> NormalizeVectors(VectorClockNode <T> vectorClock) { var newNodesForSelf = vectorClock.revision.Where(c => !this.revision.ContainsKey(c.Key)).Select(c => c.Value); var newNodesForOther = this.revision.Where(c => !vectorClock.revision.ContainsKey(c.Key)).Select(c => c.Value); foreach (var version in newNodesForSelf) { this.revision.Add(version.NodeID, new VectorClockNodeVersion(version.NodeID, 0)); } foreach (var version in newNodesForOther) { vectorClock.revision.Add(version.NodeID, new VectorClockNodeVersion(version.NodeID, 0)); } return(vectorClock); }
private bool IsDescendantOf(VectorClockNode <T> otherVectorClock) { return(otherVectorClock.Revision.All(a => this.revision[a.NodeID].Version >= a.Version)); }
public virtual void QueueEvent(VectorClockNode <T> eventSource) { syncRequestQueue.Enqueue(eventSource); }
public virtual bool TryRegisterNode(VectorClockNode <T> node) { return(nodeMesh.TryAdd(node.NodeID, node)); }
public static VectorClockSyncResult <T> Conflictual(VectorClockNode <T> currentNode, VectorClockConflict <T> conflict) => new VectorClockSyncResult <T>(currentNode, null, conflict);
public static VectorClockSyncResult <T> Successfull(VectorClockNode <T> currentNode, VectorClockNode <T> solution) => new VectorClockSyncResult <T>(currentNode, solution, null);
private VectorClockSyncResult(VectorClockNode <T> currentNode, VectorClockNode <T> solution, VectorClockConflict <T> conflict) { CurrentNode = currentNode; Solution = solution; Conflict = conflict; }