Пример #1
0
        /// <summary>
        /// Called on the data heap server nodes during replication, performs CRDT merge operation by
        /// taking the local state represented by this instance and merging another version(s) which came from other heap nodes.
        /// The function returns a result of the merge (conflict-free by definition) which is then used as the most
        /// current state instance, or null if this instance already represents the most current instance.
        /// WARNING: Per CvRDT definition, this operation is COMMUTATIVE, ASSOCIATIVE, and IDEMPOTENT.
        /// Failure to comply with these requirements may result in an infinite inter-node rotary traffic pattern.
        /// </summary>
        /// <param name="node">Node where data change takes place</param>
        /// <param name="space">Space where this object is stored</param>
        /// <param name="others">Other versions got form other nodes</param>
        /// <returns>Object instance which results from merge or null if THIS instance already represents the latest eventual state and no changes are necessary</returns>
        protected virtual HeapObject DoCrdt_Merge(IServerNodeContext node, ISpace space, IEnumerable <HeapObject> others)
        {
            var result = this;

            foreach (var ver in others)
            {
                if (ver.Sys_VerUtc > result.Sys_VerUtc)
                {
                    result = ver;
                }
            }

            return(result == this ? null : result);
        }
Пример #2
0
        /// <summary>
        /// Called by the data heap server nodes during replication, performs CRDT merge operation by
        /// taking the local state represented by this instance and merging another version(s) which came from other heap nodes.
        /// The function returns a result of the merge (conflict-free by definition) which is then used as the most
        /// current state instance, or null if this instance already represents the most current instance.
        /// WARNING: Per CvRDT definition, this operation is COMMUTATIVE, ASSOCIATIVE, and IDEMPOTENT.
        /// Failure to comply with these requirements may result in an infinite inter-node rotary traffic pattern.
        /// </summary>
        /// <param name="node">Node where data change takes place</param>
        /// <param name="space">Space where this object is stored</param>
        /// <param name="others">Other versions got form other nodes</param>
        /// <returns>
        /// Object instance which results from merge or null if THIS instance already represents the latest eventual state and no changes are necessary.
        /// You either return null, or one of "others" OR you can return a brand new object (not this or others), in which case the system treats it a as
        /// a brand new version performing necessary version stamping via `Crdt_Set()`
        /// </returns>
        internal HeapObject Crdt_Merge(IServerNodeContext node, ISpace space, IEnumerable <HeapObject> others)
        {
            if (others == null)
            {
                return(null);
            }
            if (!others.Any())
            {
                return(null);
            }

            var t = this.GetType();

            others.IsTrue(v => v.All(one => one.GetType() == t && one.Sys_Id == this.Sys_Id), "Non empty version for the same Sys_Id");

            return(DoCrdt_Merge(node, space, others).IsTrue(r => r == null || r.GetType() == t, "Returned type mismatch"));
        }
Пример #3
0
 /// <summary>
 /// Called by the server node, "seals" the data version by stamping appropriate object attributes.
 /// The node calls this method when the data is SET(Updated), but typically NOT when it is synchronized/merged
 /// unless a merge yields a brand new version of data.
 /// You must always call the base implementation
 /// </summary>
 /// <param name="node">Node where data change takes place</param>
 /// <param name="space">Space where this object is stored</param>
 /// <param name="newState">The new version state</param>
 /// <remarks>
 /// This is an extension point for any kind of CRDT mechanism, e.g. you can use vector clocks by
 /// storing the appropriate value in your derived type fields and then extend this method to populate the object version
 /// accordingly.
 /// </remarks>
 protected internal virtual void Crdt_Set(IServerNodeContext node, ISpace space, State newState)
 {
     Sys_VerState = newState;
     Sys_VerUtc   = node.UtcNow.ToMillisecondsSinceUnixEpochStart();
     Sys_VerNode  = node.Node.NodeId;
 }