Beispiel #1
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());
            }
        }
Beispiel #2
0
        private static void RunStupidModel()
        {
            int gridRes = 100;               //2d resolution
            //each grid cell can 'see' +- 4 cells in all direction. All 'motion' is done via communication
            //hence R = 4 / gridRes
            float r = 4.5f / gridRes;

            BaseDB.ConfigContainer config = new BaseDB.ConfigContainer()
            {
                extent = Int3.One, r = r, m = r * 0.5f
            };
            Simulation.Configure(new ShardID(Int3.Zero, 0), config, true);
            Vec3 outlierCoords = Simulation.MySpace.Min;

            var ctx           = new SimulationContext(true);
            var intermediate0 = new IntermediateSDS();

            intermediate0.entities = new EntityPool(MakeGrid2D(gridRes), ctx);
            //EntityTest.RandomDefaultPool(100);
            intermediate0.ic = InconsistencyCoverage.NewCommon();
            intermediate0.inputConsistent = true;
            intermediate0.localChangeSet  = new EntityChangeSet();

            SDSStack.Entry root = new SDSStack.Entry(
                new SDS(0, intermediate0.entities.ToArray(), intermediate0.ic),
                intermediate0);
            //Assert.IsTrue(root.IsFullyConsistent);

            SDSStack stack = Simulation.Stack;

            stack.ResetToRoot(root);

            for (int i = 0; i < 13; i++)
            {
                //Assert.IsNotNull(stack.NewestSDS.FinalEntities, i.ToString());
                var temp = stack.AllocateGeneration(i + 1);
                ctx.SetGeneration(i + 1);
                var comp = new SDSComputation(new DateTime(), ExtMessagePack.CompleteBlank, TimeSpan.FromMilliseconds(10), ctx);
                //ComputationTests.AssertNoErrors(comp, "comp");
                //Assert.IsTrue(comp.Intermediate.inputConsistent);

                var sds = comp.Complete();
                stack.Insert(sds);
                //Assert.IsTrue(sds.IsFullyConsistent);

                //Assert.AreEqual(sds.FinalEntities.Length, gridRes * gridRes);

                int   numBugs      = 0;
                int   numPredators = 0;
                int   numConflicts = 0;
                float totalFood    = 0;
                foreach (var e in sds.Item1.FinalEntities)
                {
                    Habitat h = (Habitat)Helper.Deserialize(e.SerialLogicState);
                    if (h.bug.HasAnimal)
                    {
                        numBugs++;
                    }
                    if (h.predator.HasAnimal)
                    {
                        numPredators++;
                        if (h.bug.HasAnimal)
                        {
                            numConflicts++;
                        }
                    }
                    totalFood += h.food;
                }

                Console.WriteLine("Population: b=" + numBugs + ", p=" + numPredators + ", c=" + numConflicts + "; Food=" + totalFood);
            }
        }
Beispiel #3
0
        public static void Run(ShardID myID)
        {
            //Host.Domain = ;
            listener            = new Listener(h => FindLink(h));
            observationListener = new ObservationLink.Listener(0);
            Consensus           = new Consensus.Interface(
                new FullShardAddress(myID, null, listener.Port, 0, observationListener.Port),
                true, Interface.ThreadOperations.Everything, new DefaultNotify());
            Configure(myID, BaseDB.Config, false);

            AdvertiseOldestGeneration(0);



            Log.Message("Polling SDS state...");
            DB.Begin(myID.XYZ, s => FetchIncoming(null, s), s => FetchIncoming(null, s));

            SimulationContext ctx = new SimulationContext(false);

            while (true)
            {
                CheckIncoming(TimingInfo.Current.TopLevelGeneration, ctx);
                if (stack.HasEntries)
                {
                    break;
                }
                Thread.Sleep(1000);
                Console.Write('.');
                Console.Out.Flush();
            }
            var sds = stack.NewestConsistentSDS;

            Messages.TrimGenerations(sds.Generation - 1);
            Consensus.ForwardMessageGeneration(sds.Generation);
            Log.Message(" done. Waiting for logic assemblies to finish loading...");

            foreach (var e in sds.FinalEntities)
            {
                var logic = e.MyLogic as DynamicCSLogic;
                if (logic != null)
                {
                    logic.FinishLoading(e.ID, TimeSpan.FromMinutes(5));
                }
            }
            Log.Message(" done");


            Log.Message("Start Date=" + BaseDB.Timing.startTime);

            //{
            //	foreach (var link in neighbors)
            //		DB.BeginFetch(link.InboundRCSStackID);
            //}


//			Log.Message("Catching up to g"+ TimingInfo.Current.TopLevelGeneration);
            while (stack.NewestFinishedSDSGeneration < TimingInfo.Current.TopLevelGeneration)
            {
                UpdateTitle("Catching up g" + stack.NewestFinishedSDSGeneration + "/" + TimingInfo.Current.TopLevelGeneration);
                //Log.Message("Catching up to g" + TimingInfo.Current.TopLevelGeneration);
                Console.Write(".");
                Console.Out.Flush();
                int currentGen = stack.NewestFinishedSDSGeneration;
                int nextGen    = currentGen + 1;
                ctx.SetGeneration(nextGen);
                stack.Append(new SDS(nextGen));
                Debug.Assert(!stack.NewestRegisteredEntry.IsFinished);
                stack.Insert(new SDSComputation(Clock.Now, Messages.GetMessages(currentGen), TimingInfo.Current.EntityEvaluationTimeWindow, ctx).Complete());
                Debug.Assert(stack.NewestRegisteredEntry.IsFinished);
                CheckIncoming(TimingInfo.Current.TopLevelGeneration, ctx);
            }
            Log.Message("done. Starting main loop...");


            SDSComputation mainComputation = null, recoveryComputation = null;             //main computation plus one recovery computation max
            int            lastRecoveryIndex = -1;

            while (true)
            {
                var timing = TimingInfo.Current;
                CheckIncoming(timing.TopLevelGeneration, ctx);
                Log.Minor("TLG " + stack.NewestFinishedSDSGeneration + "/" + timing.TopLevelGeneration + " @recoveryStepIndex " + timing.LatestRecoveryStepIndex);
                {
                    var    newest = stack.NewestFinishedSDS;
                    string title  = ID + " g" + newest.Generation + " " + (float)(newest.IC.Size.Product - newest.IC.OneCount) * 100 / newest.IC.Size.Product + "% consistent";
                    var    con    = stack.NewestConsistentSDS;
                    if (con != newest)
                    {
                        title += ", newest consistent at g" + con.Generation;
                    }
                    title += ", rec " + timing.LatestRecoveryStepIndex;
                    UpdateTitle(title);
                }

                int newestSDSGeneration = stack.NewestFinishedSDSGeneration;
                if (mainComputation == null)
                {
                    Debug.Assert(stack.NewestRegisteredEntry.IsFinished);
                    Debug.Assert(newestSDSGeneration == stack.NewestRegisteredSDSGeneration);
                    Debug.Assert(stack.NewestConsistentSDSIndex != -1);
                }
                if (recoveryComputation != null && Complete(recoveryComputation, timing, timing.TopLevelGeneration != newestSDSGeneration))
                {
                    recoveryComputation = null;
                }
                if (mainComputation != null && Complete(mainComputation, timing, timing.TopLevelGeneration != newestSDSGeneration && timing.TopLevelGeneration > mainComputation.Generation))
                {
                    newestSDSGeneration = stack.NewestFinishedSDSGeneration;
                    Debug.Assert(stack.NewestRegisteredEntry.IsFinished);
                    Debug.Assert(newestSDSGeneration == stack.NewestRegisteredSDSGeneration);
                    Debug.Assert(stack.NewestConsistentSDSIndex != -1);
                    mainComputation = null;
                }

                if (recoveryComputation != null && mainComputation != null)
                {
                    Clock.SleepUntil(Helper.Min(recoveryComputation.Deadline, mainComputation.Deadline));
                }
                else
                if (recoveryComputation != null)
                {
                    Clock.SleepUntil(recoveryComputation.Deadline);
                }
                else
                if (mainComputation != null)
                {
                    Clock.SleepUntil(mainComputation.Deadline);
                }

                if (recoveryComputation != null)                        //recovery computations are analogue to main computation, so main computation will not be done. but recovery must be
                {
                    continue;
                }

                if (mainComputation == null && timing.TopLevelGeneration > newestSDSGeneration)
                {
                    //fast forward: process now. don't care if we're at the beginning
                    Debug.Assert(stack.NewestRegisteredEntry.IsFinished);
                    Debug.Assert(newestSDSGeneration == stack.NewestRegisteredSDSGeneration);
                    Debug.Assert(stack.NewestConsistentSDSIndex != -1);
                    int nextGen = newestSDSGeneration + 1;
                    Log.Message("Processing next TLG g" + nextGen);
                    stack.Insert(new SDS(nextGen));
                    ctx.SetGeneration(nextGen);
                    Debug.Assert(mainComputation == null);
                    Consensus.ForceCommitGECIfLeader(newestSDSGeneration);
                    mainComputation = new SDSComputation(timing.NextMainApplicationDeadline, Messages.GetMessages(newestSDSGeneration), timing.EntityEvaluationTimeWindow, ctx);
                }


                if (timing.ShouldStartRecovery(ref lastRecoveryIndex))
                {
                    //see if we can recover something
                    int oldestInconsistentSDSIndex = stack.NewestConsistentSDSIndex + 1;                        //must be > 0
                    int top = Math.Min(stack.Size - 1, stack.ToIndex(timing.TopLevelGeneration));
                    if (oldestInconsistentSDSIndex <= top)
                    {
                        int end            = mainComputation == null ? top + 1 : top;
                        int recoverAtIndex = oldestInconsistentSDSIndex;
                        int currentGen     = stack[recoverAtIndex].Generation;
                        for (; recoverAtIndex < end; recoverAtIndex++)
                        {
                            var current = stack[recoverAtIndex];
                            if (current.SignificantInboundChange)
                            {
                                break;
                            }

                            var check = CheckMissingRCS(current);

                            if (check.ShouldRecoverThis)
                            {
                                break;
                            }
                        }
                        if (recoverAtIndex < end)
                        {
                            var deadline = timing.GetRecoveryStepApplicationDeadline(lastRecoveryIndex);
                            Log.Message("Recovering #" + recoverAtIndex + "/" + top + ", g" + stack[recoverAtIndex].Generation + ", deadline=" + deadline);
                            //precompute:
                            ctx.SetGeneration(stack[recoverAtIndex].Generation);
                            recoveryComputation = new SDSComputation(deadline, Messages.GetMessages(ctx.GenerationNumber - 1), timing.EntityEvaluationTimeWindow, ctx);
                            //now wait for remote RCS...
                        }
                    }
                }
            }
        }