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));
 }
Esempio n. 8
0
 public static VectorClockSyncResult <T> Conflictual(VectorClockNode <T> currentNode, VectorClockConflict <T> conflict)
 => new VectorClockSyncResult <T>(currentNode, null, conflict);
Esempio n. 9
0
 public static VectorClockSyncResult <T> Successfull(VectorClockNode <T> currentNode, VectorClockNode <T> solution)
 => new VectorClockSyncResult <T>(currentNode, solution, null);
Esempio n. 10
0
 private VectorClockSyncResult(VectorClockNode <T> currentNode, VectorClockNode <T> solution, VectorClockConflict <T> conflict)
 {
     CurrentNode = currentNode;
     Solution    = solution;
     Conflict    = conflict;
 }