Example #1
0
        public static async Task PutAsync(SerialSDS serial, bool forceReplace)
        {
            if (SDSStore == null)
            {
                return;                 //tests
            }
            try
            {
                Log.Minor("Storing serial SDS in DB: g" + serial.Generation);
                if (sdsPoller != null)
                {
                    var latest = sdsPoller.Latest;
                    if (latestPut != null && latestPut.Generation > latest.Generation)
                    {
                        latest = latestPut;
                    }
                    if (serial.Generation <= latest.Generation)
                    {
                        Log.Minor("Newer already online. Rejecting update");
                        return;                         //nothing to do
                    }
                    serial._rev = latest._rev;
                }
                await PutAsync(SDSStore, serial, forceReplace, null);

                latestPut = serial;
                Log.Minor("Stored serial SDS in DB: g" + serial.Generation);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Error("Failed to store serial SDS in DB: g" + serial.Generation);
            }
        }
Example #2
0
 public static void PutNow(SerialSDS serial, bool forceReplace)
 {
     if (OnPutSDS != null)
     {
         OnPutSDS(serial);
     }
     Try(() =>
     {
         PutAsync(SDSStore, serial, forceReplace, null).Wait();
         return(true);
     }, 3);
 }
Example #3
0
        public static Tuple <SerialSDS, SerialCCS> Begin(Int3 myID, Action <SerialSDS> fetchSDS, Action <SerialCCS> fetchCCS)
        {
            sdsPoller = new DBType.ContinuousPoller <SerialSDS>(null, (collection) =>
            {
                SerialSDS latest = null;
                foreach (var candidate in collection)
                {
                    if (latest == null || latest.Generation < candidate.Generation)
                    {
                        latest = candidate;
                    }
                    else if (latest.Generation == candidate.Generation)
                    {
                        //weird, but let's check
                        if (!candidate.IC.IsEmpty)
                        {
                            throw new IntegrityViolation("SDS candidate at g=" + candidate.Generation + " is not consistent");
                        }
                        if (candidate.Generation != latest.Generation)
                        {
                            throw new IntegrityViolation("SDS candidate at g=" + candidate.Generation + " mismatch with favorite at g=" + latest.Generation);
                        }
                        var comp = new Helper.Comparator()
                                   .Append(candidate.SerialEntities, latest.SerialEntities)
                                   .Finish();
                        if (comp != 0)
                        {
                            Log.Error("Persistent SDS data mismatch at g=" + candidate.Generation);
                            if (comp < 0)
                            {
                                latest = candidate;
                            }
                        }
                    }
                }
                if (!latest.IC.IsEmpty)
                {
                    throw new IntegrityViolation("Chosen persistent SDS candidate at g=" + latest.Generation + " is not consistent");
                }
                return(latest);
            });
            sdsPoller.Start(SDSStore, myID.Encoded);
            sdsPoller.OnChange = serial => fetchSDS(serial);


            ccsPoller = new DBType.ContinuousPoller <SerialCCS>(null, (collection) =>
            {
                SerialCCS latest = null;
                foreach (var candidate in collection)
                {
                    if (latest == null || latest.Generation < candidate.Generation)
                    {
                        latest = candidate;
                    }
                    else if (latest.Generation == candidate.Generation)
                    {
                        //weird, but let's check
                        if (candidate.Generation != latest.Generation)
                        {
                            throw new IntegrityViolation("CCS candidate at g=" + candidate.Generation + " mismatch with favorite at g=" + latest.Generation);
                        }
                        var comp = new Helper.Comparator()
                                   .Append(candidate.Data, latest.Data)
                                   .Finish();
                        if (comp != 0)
                        {
                            Log.Error("Persistent CCS data mismatch at g=" + candidate.Generation);
                            if (comp < 0)
                            {
                                latest = candidate;
                            }
                        }
                    }
                }
                return(latest);
            });
            ccsPoller.Start(CCSStore, myID.Encoded);
            ccsPoller.OnChange = serial => fetchCCS(serial);

            return(new Tuple <SerialSDS, SerialCCS>(sdsPoller.Latest, ccsPoller.Latest));
        }
Example #4
0
        private static void CheckIncoming(int currentTLG, SimulationContext ctx)
        {
            Tuple <Link, object> pair;

            while (incoming.TryTake(out pair))
            {
                object obj = pair.Item2;
                Link   lnk = pair.Item1;

                if (obj is ClientMessage)
                {
                    Log.Error("Received client message via peer socket");
                    return;
                }

                if (obj is OldestGeneration)
                {
                    int gen = ((OldestGeneration)obj).Generation;
                    if (gen == lnk.OldestGeneration)
                    {
                        if (siblings.AllResponsive && siblings.OldestGeneration >= gen)
                        {
                            DB.RemoveInboundRCSsAsync(neighbors.Select(sibling => sibling.InboundRCSStackID), gen).Wait();                              //maybe only now responsive
                        }
                        Log.Minor("OldestGen update from sibling " + lnk + ": Warning: Already moved to generation " + gen);
                        return;
                    }
                    if (gen > lnk.OldestGeneration)
                    {
                        lnk.SetOldestGeneration(gen, currentTLG);
                        lnk.Filter((id, o) =>
                        {
                            SerialSDS sds = o as SerialSDS;
                            if (sds != null)
                            {
                                return(sds.Generation >= gen);
                            }
                            RCS.Serial rcs = o as RCS.Serial;
                            if (rcs != null)
                            {
                                return(rcs.Generation >= gen);
                            }
                            return(true);
                        });
                        if (siblings.AllResponsive && siblings.OldestGeneration >= gen)
                        {
                            DB.RemoveInboundRCSsAsync(neighbors.Select(sibling => sibling.InboundRCSStackID), gen).Wait();
                        }
                    }
                    return;
                }
                if (obj is Tuple <int, RCS> )
                {
                    var rcs = (Tuple <int, RCS>)obj;
                    if (rcs.Item1 <= stack.NewestConsistentSDSGeneration)
                    {
                        Log.Error("RCS update from sibling " + lnk + ": Rejected. Already moved past generation " + rcs.Item1);
                        return;
                    }
                    FetchNeighborUpdate(stack.AllocateGeneration(rcs.Item1), lnk, rcs.Item2);
                    return;
                }
                if (obj is RCS.Serial)
                {
                    RCS.Serial rcs = (RCS.Serial)obj;
                    if (rcs.Generation <= stack.NewestConsistentSDSGeneration)
                    {
                        Log.Error("RCS update from sibling " + lnk + ": Rejected. Already moved past generation " + rcs.Generation);
                        return;
                    }
                    FetchNeighborUpdate(stack.AllocateGeneration(rcs.Generation), lnk, rcs.Data);
                    return;
                }

                if (obj is SerialSDS)
                {
                    //Debug.Assert(HaveSibling(lnk));
                    SerialSDS raw = (SerialSDS)obj;
                    if (raw.Generation <= stack.OldestSDSGeneration)
                    {
                        Log.Minor("SDS update from sibling or DB: Rejected. Already moved past generation " + raw.Generation);
                        return;
                    }
                    var existing = stack.FindGeneration(raw.Generation);
                    if (existing != null && existing.IsFullyConsistent)
                    {
                        Log.Minor("SDS update from sibling or DB: Rejected. Generation already consistent: " + raw.Generation);
                        return;
                    }
                    SDS sds = raw.Deserialize();
                    if (existing != null && existing.SDS.ICMessagesAndEntitiesAreEqual(sds))
                    {
                        Log.Minor("SDS update from sibling or DB: Equal. Ignoring");
                        return;
                    }
                    if (sds.IsFullyConsistent)
                    {
                        Log.Minor("SDS update from sibling or DB: Accepted generation " + raw.Generation);
                        stack.Insert(sds);
                        return;
                    }
                    SDS merged = existing.SDS.MergeWith(sds, SDS.MergeStrategy.ExclusiveWithPositionCorrection, ctx);
                    Log.Minor("SDS update from sibling " + lnk + ": Merged generation " + raw.Generation);
                    if (merged.Inconsistency < existing.SDS.Inconsistency)
                    {
                        stack.Insert(merged);
                    }
                    if (merged.Inconsistency < sds.Inconsistency)
                    {
                        lnk.Set(new SDS.ID(ID.XYZ, raw.Generation).P2PKey, new SerialSDS(merged, Simulation.ID.XYZ));
                    }
                    return;
                }

                if (obj is Tuple <int, MessagePack> )
                {
                    //Debug.Assert(HaveSibling(lnk));
                    var m = (Tuple <int, MessagePack>)obj;
                    if (m.Item1 <= stack.OldestSDSGeneration)
                    {
                        Log.Minor("CCS update from sibling or DB: Rejected. Already moved past generation " + m.Item1);
                        return;
                    }
                    Messages.Insert(m.Item1, m.Item2);
                    return;
                }
                Log.Error("Unsupported update from sibling " + lnk + ": " + obj.GetType());
            }
        }