コード例 #1
0
ファイル: Neighborhood.cs プロジェクト: IronFox/Shard
        public static Neighborhood NewNeighborList(ShardID myAddr, Int3 extent, bool forceAllLinksPassive)
        {
            List <Link> neighbors = new List <Link>();
            Int3        at        = Int3.Zero;

            for (at.X = myAddr.X - 1; at.X <= myAddr.X + 1; at.X++)
            {
                for (at.Y = myAddr.Y - 1; at.Y <= myAddr.Y + 1; at.Y++)
                {
                    for (at.Z = myAddr.Z - 1; at.Z <= myAddr.Z + 1; at.Z++)
                    {
                        if (at == myAddr.XYZ)
                        {
                            continue;
                        }

                        if ((at >= Int3.Zero).All && (at < extent).All)
                        {
                            int linear = neighbors.Count;
                            neighbors.Add(new Link(new ShardID(at, myAddr.ReplicaLevel), at.OrthographicCompare(myAddr.XYZ) > 0 && !forceAllLinksPassive, linear, false));
                        }
                    }
                }
            }
            return(new Neighborhood(neighbors));
        }
コード例 #2
0
 private static void WriteID(NetworkStream stream, ShardID id)
 {
     stream.Write(BitConverter.GetBytes(id.X), 0, 4);
     stream.Write(BitConverter.GetBytes(id.Y), 0, 4);
     stream.Write(BitConverter.GetBytes(id.Z), 0, 4);
     stream.Write(BitConverter.GetBytes(id.ReplicaLevel), 0, 4);
 }
コード例 #3
0
ファイル: LinkTests.cs プロジェクト: IronFox/Shard
 public Receiver(DataSetReceiverState state, int port, ShardID bindID)
 {
     this.state     = state;
     Passive        = new Link(new Address("localhost", port), false, 0, false, bindID);
     Passive.OnData = OnData;
     Listener       = new Listener(h => Passive, port);
 }
コード例 #4
0
        public void AddSector(Address host, ShardID idk, Action <Sector> onCreate)
        {
            Sector rs;

            if (sectors.TryGetValue(host, out rs))
            {
                onCreate?.Invoke(rs);
                return;
            }


            OnCreateObject(idk.ToString(), sec =>
            {
                sec.transform.parent = transform;
                Sector s             = sec.AddComponent <Sector>();
                s.CubePrototype      = cubePrototype;
                s.EntityPrototype    = entityPrototype;
                s.Host       = host;
                s.ExpectedID = idk;

                sectors.Add(host, s);
                s.onNewID = id =>
                {
                };
                s.OnNewNeighbor = (id, addr) =>
                {
                    AddSector(addr, id);
                };
                onCreate?.Invoke(s);
            });
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: IronFox/Shard
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.Error.WriteLine("Usage: <program> <db address:port> <shard ID.");
                Environment.Exit(-1);
            }
            try
            {
                BaseDB.Connect(new Address(args[0]));
                ShardID id = ShardID.Decode(args[1]);

                var rs = BaseDB.TryGetAddress(id);
                while (rs.IsEmpty)
                {
                    Thread.Sleep(1000);
                    rs = BaseDB.TryGetAddress(id);
                }
                Console.WriteLine(rs.PeerAddress);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                Environment.Exit(-1);
            }
        }
コード例 #6
0
 public static Link FindLink(ShardID id)
 {
     if (id.XYZ == ID.XYZ)
     {
         return(siblings?.Find(id));
     }
     return(neighbors?.Find(id));
 }
コード例 #7
0
 public FullShardAddress(ShardID id, string host, int peerPort, int consensusPort, int observerPort)
 {
     ShardID       = id;
     Host          = host;
     PeerPort      = peerPort;
     ConsensusPort = consensusPort;
     ObserverPort  = observerPort;
 }
コード例 #8
0
 public SimulationRun(BaseDB.ConfigContainer config, ShardID localShardID, bool allLinksArePassive = true)
 {
     //BaseDB.ConfigContainer config = new BaseDB.ConfigContainer() { extent = Int3.One, r = 1f / 8, m = 1f / 16 };
     Simulation.Configure(localShardID, config, allLinksArePassive);
     ctx      = new SimulationContext(config, Simulation.SDToBox(localShardID.XYZ, config.extent), allLinksArePassive);
     messages = new MessageHistory(0, new MessagePack[] { MessagePack.CompleteBlank });
     Notify   = new MyNotify(this);
 }
コード例 #9
0
            public SimulationRun(BaseDB.ConfigContainer config, ShardID localShardID, IEnumerable <Entity> entities, bool allLinksArePassive = true)
            {
                //BaseDB.ConfigContainer config = new BaseDB.ConfigContainer() { extent = Int3.One, r = 1f / 8, m = 1f / 16 };
                Simulation.Configure(localShardID, config, allLinksArePassive);
                ctx    = new SimulationContext(config, Simulation.SDToBox(localShardID.XYZ, config.extent), allLinksArePassive);
                Notify = new MyNotify(this);

                FeedEntities(entities);
            }
コード例 #10
0
 public static void GetAddress(ShardID id, Action <FullShardAddress> onGetAddress)
 {
     if (OverrideAddressRequestFunction != null)
     {
         onGetAddress(OverrideAddressRequestFunction(id));
         return;
     }
     hostRequests.Get(HostsStore, id, a => onGetAddress(a.GetFullAddress(id)));
 }
コード例 #11
0
        public static Address TryGetConsensusAddress(ShardID id)
        {
            var h = hostRequests.TryGet(HostsStore, id);

            if (h == null)
            {
                return(new Address());
            }
            return(h.ConsensusAddress);
        }
コード例 #12
0
        public void AddSector(Address host, ShardID id)
        {
            Sector existing;

            if (shardMap.TryGetValue(id, out existing))
            {
                existing.Host = host;
                return;
            }
            AddSector(host, id, sec => shardMap.Add(id, sec));
        }
コード例 #13
0
ファイル: Neighborhood.cs プロジェクト: IronFox/Shard
 public Link Find(ShardID id)
 {
     foreach (var n in links)
     {
         if (n.ID == id)
         {
             return(n);
         }
     }
     return(null);
 }
コード例 #14
0
        public static FullShardAddress TryGetAddress(ShardID id)
        {
            if (OverrideAddressRequestFunction != null)
            {
                return(OverrideAddressRequestFunction(id));
            }
            var h = hostRequests.TryGet(HostsStore, id);

            if (h == null)
            {
                return(new FullShardAddress());
            }
            return(h.GetFullAddress(id));
        }
コード例 #15
0
ファイル: Neighborhood.cs プロジェクト: IronFox/Shard
        public static Neighborhood NewSiblingList(ShardID myAddr, int replicaLevel, bool forceAllLinksPassive)
        {
            int          at = 0;
            Neighborhood n  = new Neighborhood(replicaLevel - 1);

            for (int i = 0; i < replicaLevel; i++)
            {
                if (i != myAddr.ReplicaLevel)
                {
                    n.links[at] = new Link(new ShardID(myAddr.XYZ, i), i > myAddr.ReplicaLevel && !forceAllLinksPassive, at, true);
                    at++;
                }
            }
            return(n);
        }
コード例 #16
0
        /// <summary>
        /// Creates a new link to a sibling shard
        /// </summary>
        /// <param name="remoteHost">Address of the remote shard</param>
        /// <param name="isActive">Actively establish the connection. If false, wait for inbound connection</param>
        /// <param name="linearIndex">Linear index in the neighborhood</param>
        /// <param name="isSibling">True if this is a link to a sibling shard (not a neighbor)</param>
        public Link(Address remoteHost, bool isActive, int linearIndex, bool isSibling, ShardID bindID)
        {
            ID          = bindID;
            IsSibling   = isSibling;
            LinearIndex = linearIndex;
            UpdateAddress(remoteHost);
            IsActive = isActive;
            if (isActive)
            {
                StartConnectionThread();
            }

            writeThread = new Thread(new ThreadStart(WriteMain));
            writeThread.Start();

            Log.Message(Name + ": Created");
        }
コード例 #17
0
        public static void Configure(ShardID addr, BaseDB.ConfigContainer config, bool forceAllLinksPassive)
        {
            CSLogicProvider.AsyncFactory = DB.GetLogicProviderAsync;

            ID      = addr;
            gridExt = config.extent;
            Ranges  = ToRanges(config);
            MySpace = SDToBox(addr.XYZ, config.extent);


            InconsistencyCoverage.CommonResolution = (int)Math.Ceiling(1f / Ranges.R);

            if (Extent.ReplicaLevel > 1)
            {
                siblings = Neighborhood.NewSiblingList(addr, Extent.ReplicaLevel, forceAllLinksPassive);
            }
            neighbors = Neighborhood.NewNeighborList(addr, Extent.XYZ, forceAllLinksPassive);
        }
コード例 #18
0
        public Interface(Configuration.Member self, Address selfAddress, Int3 myCoords, ThreadOperations threadOps, INotifiable notify, Action <Address> onAddressBound = null) : base(self)
        {
            Notify    = notify;
            ThreadOps = threadOps;
            var cfg = BuildConfig();

            if (!cfg.ContainsIdentifier(self))
            {
                throw new ArgumentOutOfRangeException("Given self address is not contained by current SD configuration");
            }
            Log.Message("Starting consensus with configuration " + cfg);
            actualPort = Start(cfg, selfAddress, onAddressBound);
            MyID       = new ShardID(myCoords, self.Identifier);
            if (threadOps != ThreadOperations.Nothing)
            {
                gecThread = new Thread(new ThreadStart(GECThreadMain));
                gecThread.Start();
            }
        }
コード例 #19
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                throw new ArgumentException("Missing arguments. Usage: Executable <DBHost> <ShardID>");
            }
            int at     = 0;
            var dbHost = new Address(args[at++]);

            BaseDB.Connect(dbHost);            //,"admin","1234");
            ShardID addr = ShardID.Decode(args[at++]);

            BaseDB.BeginPullConfig(addr.XYZ);

            iface = new Consensus.Interface(addr, -1, 0, true, Consensus.Interface.ThreadOperations.CheckConfiguration, new Notify(error =>
            {
                Log.Error(error);
                iface.Dispose();
                Log.Message("Shutting down");
            }, () => iface));
            iface.Notify.OnConsensusChange(Consensus.Status.NotEstablished, null);

            iface.AwaitClosure();
        }
コード例 #20
0
 public void ConnectTo(Address dbHost, ShardID id)
 {
     BaseDB.Connect(dbHost);
     BaseDB.GetAddress(id, addr => AddSector(addr.ObserverAddress, addr.ShardID));
 }
コード例 #21
0
        private void ThreadMain()
        {
            if (lastHost.IsEmpty)
            {
                return;
            }
            Debug.Log("Sector: Thread active");

            try
            {
                while (!stop)
                {
                    try
                    {
                        Debug.Log("Attempting to connect to " + lastHost);
                        client = new TcpClient(lastHost.Host, lastHost.Port);
                        var stream = new LZ4.LZ4Stream(client.GetStream(), LZ4.LZ4StreamMode.Decompress);
                        var f      = new BinaryFormatter();
                        CSLogicProvider.AsyncFactory = ResolveProvider;

                        Debug.Log("Sector: Connected to " + lastHost);

                        while (client.Connected)
                        {
                            Debug.Log("Sector: Deserializing next object");
                            var obj = f.UnsafeDeserialize(stream, null);
                            Debug.Log("Sector: Deserialized object " + obj);

                            if (obj is ShardID)
                            {
                                privateID = (ShardID)obj;
                                Debug.Log("Sector: ID updated to " + privateID);
                                OnNewNeighbor(privateID, lastHost);
                            }
                            else if (obj is ObserverTimingInfo)
                            {
                                secondsPerTLG = (float)((ObserverTimingInfo)obj).msPerTLG / 1000f;
                            }
                            else if (obj is CSLogicProvider)
                            {
                                var prov = (CSLogicProvider)obj;
                                TaskCompletionSource <CSLogicProvider> entry;
                                while (!providerMap.TryGetValue(prov.AssemblyName, out entry))
                                {
                                    providerMap.TryAdd(prov.AssemblyName, new TaskCompletionSource <CSLogicProvider>());
                                }
                                if (!entry.Task.IsCompleted)
                                {
                                    entry.SetResult(prov);
                                }
                                Debug.Log("Sector: Added new provider " + prov.AssemblyName);
                            }
                            else if (obj is FullShardAddress)
                            {
                                var h = (FullShardAddress)obj;
                                newNeighbors.Add(h);
                            }
                            else if (obj is SDS)
                            {
                                SDS sds = (SDS)obj;
                                //Debug.Log("Sector: Got new SDS. Deserializing entities...");

                                foreach (var e in sds.FinalEntities)
                                {
                                    var logic = e.MyLogic as DynamicCSLogic;
                                    if (logic != null)
                                    {
                                        try
                                        {
                                            logic.FinishLoading(e.ID, TimeSpan.FromSeconds(1));
                                        }
                                        catch (ExecutionException ex)
                                        {
                                            Debug.LogException(ex);
                                        }
                                    }
                                }
                                //Debug.Log("Sector: SDS processed. Signalling change");
                                SDS        = sds;
                                sdsChanged = true;
                            }
                        }
                    }
                    catch (SocketException ex)
                    {
                        Debug.LogException(ex);
                    }
                    catch (IOException ex)
                    {
                        Debug.LogException(ex);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogException(ex);
                        Debug.Log("Weird type: " + ex.GetType());
                    }
                    try
                    {
                        client.Close();
                    }
                    catch { };
                    {
                        var naddr = BaseDB.TryGetAddress(ExpectedID);
                        if (!naddr.IsEmpty)
                        {
                            lastHost = naddr.ObserverAddress;
                        }
                    }
                    Debug.Log("Waiting, then retrying");
                    Thread.Sleep(2000);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError("Encountered terminal exception");
                Debug.LogException(ex);
            }
        }
コード例 #22
0
        private void ThreadMain()
        {
            Message("Starting Read");

            BinaryReader reader = new BinaryReader(netStream);

            try
            {
                var f = new BinaryFormatter();

                byte[] header = new byte[8];
                while (!closed)
                {
                    reader.RemainingBytes = 8;
                    uint channel = reader.NextUInt();
                    reader.RemainingBytes = reader.NextInt();


                    try
                    {
                        switch (channel)
                        {
                        case (uint)ChannelID.RegisterLink:
                            ShardID remoteID = reader.NextShardID();
                            ShardID localID  = reader.NextShardID();
                            if (localID != Simulation.ID)
                            {
                                throw new IntegrityViolation("Remote shard expected this shard to be " + localID + ", not " + Simulation.ID);
                            }
                            var lnk = linkLookup?.Invoke(remoteID);
                            if (lnk == null)
                            {
                                throw new IntegrityViolation("Remote shard identifies as " + remoteID + ", but this is not a known neighbor of this shard " + Simulation.ID);
                            }
                            lnk.SetPassiveClient(client);
                            Abandon();
                            break;

                        case (uint)ChannelID.RegisterReceiver:
                            Guid guid = reader.NextGuid();
                            if (!guids.Contains(guid))
                            {
                                Message("Authenticating as " + guid);
                                guids.Add(guid);
                                while (!guidMap.TryAdd(guid, this))
                                {
                                    InteractionLink link;
                                    if (guidMap.TryRemove(guid, out link))
                                    {
                                        Message("Was already registered by " + link + ". Replacing...");
                                    }
                                }
                                Message("Authenticated as " + guid);
                                OnRegisterReceiver?.Invoke(guid);
                            }
                            break;

                        case (uint)ChannelID.ShardLookup:
                        {
                            ShardID id   = reader.NextShardID();
                            var     addr = BaseDB.TryGetAddress(id);
                            using (MemoryStream ms = new MemoryStream())
                            {
                                var str = Encoding.ASCII.GetBytes(addr.Host);
                                ms.Write(id.AsBytes, 0, 16);
                                ms.Write(BitConverter.GetBytes(str.Length), 0, 4);
                                ms.Write(str, 0, str.Length);
                                ms.Write(BitConverter.GetBytes((ushort)addr.PeerPort), 0, 2);
                                Send(new OutPackage((uint)ChannelID.ShardLookupResponse, ms.ToArray()));
                            }
                        }
                        break;

                        case (uint)ChannelID.UnregisterReceiver:
                        {
                            guid = reader.NextGuid();
                            if (guids.Contains(guid))
                            {
                                Message("De-Authenticating as " + guid);
                                guids.Remove(guid);
                                guidMap.TryRemove(guid);
                                OnUnregisterReceiver?.Invoke(guid);
                            }
                        }
                        break;

                        case (uint)ChannelID.SendMessage:
                        {
                            Guid   from       = reader.NextGuid();
                            Guid   to         = reader.NextGuid();
                            Guid   id         = reader.NextGuid();
                            int    msgChannel = reader.NextInt();
                            byte[] data       = reader.NextBytes();

                            //int targetGen = Simulation.EstimateNextSuitableMessageTargetGeneration();
                            if (!guids.Contains(from))
                            {
                                Error("Not registered as " + from + ". Ignoring message");
                            }
                            else
                            {
                                //int gen = Simulation.Stack.NewestFinishedSDSGeneration;
                                ClientMessage msg = new ClientMessage(new ClientMessageID(from, to, id, msgChannel, orderIndex), data);

                                var sender = new Address(this.endPoint);
                                Simulation.Consensus?.Dispatch(msg, sender);
                                OnMessage?.Invoke(msg, sender);
                            }
                        }
                        break;
                        }
                    }
                    catch (SerializationException ex)
                    {
                        Error(ex);
                    }
                    reader.SkipRemaining();
                }
            }
            catch (SocketException)
            {}
            catch (Exception ex)
            {
                Error(ex);
            }
            Close();
        }
コード例 #23
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...
                        }
                    }
                }
            }
        }
コード例 #24
0
        // Update is called once per frame
        public void Update()
        {
            {
                FullShardAddress t;
                while (newNeighbors.TryTake(out t))
                {
                    Debug.Log(name + ": received neighbor update: " + t);
                    OnNewNeighbor(t.ShardID, t.ObserverAddress);
                }
            }



            if (sdsChanged)
            {
                sdsChanged = false;

                {
                    var id = privateID;
                    if (id != publicID)
                    {
                        Debug.Log("ID change detected: " + id);
                        publicID       = id;
                        name           = publicID.ToString();
                        transform.name = publicID.ToString();
                        onNewID?.Invoke(id);
                        if (cube != null)
                        {
                            cube.transform.position = Convert(publicID.XYZ) * Scale;
                        }
                    }
                }


                //Debug.Log("Sector: processing change");
                updateNo++;

                SDS source = SDS;
                //Debug.Log("Sector: got "+transform.childCount+" children");
                LazyList <GameObject> toDestroy = new LazyList <GameObject>();
                foreach (Transform child in transform)
                {
                    var obj = child.gameObject;
                    if (obj.name == "cube")
                    {
                        //Debug.Log("Sector: got cube");
                        continue;
                    }
                    if (obj.hideFlags == HideFlags.HideAndDontSave)
                    {
                        continue;
                    }
                    obj.hideFlags = HideFlags.HideAndDontSave;
                    obj.GetComponent <Renderer>().enabled = false;

                    if (!availableEntityObjects.ContainsKey(obj.name))
                    {
                        availableEntityObjects.Add(obj.name, obj);
                    }
                    else
                    {
                        toDestroy.Add(obj);
                    }
                }
                foreach (var obj in toDestroy)
                {
                    if (availableEntityObjects.ContainsValue(obj))
                    {
                        Debug.LogError("Object " + obj.name + " still in use");
                    }
                    else
                    {
                        Destroy(obj);
                    }
                }


                //Debug.Log("Sector: recovered " + availableEntityObjects.Count + " objects");
                int reused = 0;
                foreach (var e in source.FinalEntities)
                {
                    GameObject obj;
                    var        next = Convert(e.ID.Position) * Scale;
                    Vector3    prev = next;
                    string     key  = e.ID.Guid.ToString();
                    if (!availableEntityObjects.ContainsKey(key))
                    {
                        obj = entityPrototype != null?Instantiate(entityPrototype, transform) : new GameObject();

                        obj.GetComponent <Renderer>().material.color = myColor;
                        obj.transform.parent = transform;
                        obj.name             = key;
                    }
                    else
                    {
                        obj = availableEntityObjects[key];
                        availableEntityObjects.Remove(key);
                        if (obj == null)
                        {
                            Debug.LogError("Object " + key + " is null. Bad shit will happen");
                        }
                        obj.hideFlags = HideFlags.None;
                        obj.GetComponent <Renderer>().enabled = true;
                        prev = obj.transform.position;
                        reused++;
                    }
                    var c = obj.GetComponent <EntityComponent>();
                    if (c == null)
                    {
                        c = obj.AddComponent <EntityComponent>();
                    }
                    c.SetState(next - Convert(e.Velocity) * Scale, next, secondsPerTLG);
                    obj.transform.position = next;
                }
                //Debug.Log("Sector: got " + transform.childCount + " children, reusing "+reused);
            }
        }
コード例 #25
0
 public static Box ShardIDToBox(ShardID addr, ShardID ext)
 {
     return(Box.OffsetSize(new Vec3(addr.XYZ), new Vec3(1), addr.XYZ + 1 >= ext.XYZ));
 }
コード例 #26
0
 /// <summary>
 /// Creates a new link to a sibling shard
 /// </summary>
 /// <param name="id">Remote shard ID</param>
 /// <param name="isActive">Actively establish the connection. If false, wait for inbound connection</param>
 /// <param name="linearIndex">Linear index in the neighborhood</param>
 /// <param name="isSibling">True if this is a link to a sibling shard (not a neighbor)</param>
 public Link(ShardID id, bool isActive, int linearIndex, bool isSibling) : this(BaseDB.TryGetPeerAddress(id), isActive, linearIndex, isSibling, id)
 {
 }
コード例 #27
0
 internal FullShardAddress GetFullAddress(ShardID id)
 {
     return(new FullShardAddress(id, host, peerPort, consensusPort, observerPort));
 }
コード例 #28
0
ファイル: Program.cs プロジェクト: IronFox/Shard
        static void Main(string[] args)
        {
            //RunStupidModel();
            //return;



            if (args.Length < 2)
            {
                Console.Error.WriteLine("Usage: shard <db url> <my addr> | shard <db url> --setup");
                return;
            }

            try
            {
                int at     = 0;
                var dbHost = new Address(args[at++]);
                BaseDB.Connect(dbHost);                //,"admin","1234");
                ShardID addr = ShardID.Decode(args[at++]);


                bool haveConfig = BaseDB.BeginPullConfig(addr.XYZ);
                if (!haveConfig)
                {
                    Log.Error("Failed to establish connection to database");
                    Environment.Exit(-1);
                }

                Log.Message("Setting up clock");
                Clock.NTPHost = BaseDB.Config.ntp;

                while (Clock.NumQueries < 1)
                {
                    Thread.Sleep(100);
                }
                Log.Message("Starting up");



#if DRY_RUN
                if (addr == new ShardID())                  //root
                {
                    Log.Message("Resetting timer");
                    while (true)
                    {
                        Thread.Sleep(100);
                        var t = BaseDB.Timing;
                        if (t == null)
                        {
                            continue;
                        }

                        var n = Clock.Now + TimeSpan.FromSeconds(10);
                        t.startTime          = n.ToShortDateString() + " " + n.ToLongTimeString();
                        t.msGenerationBudget = 3000;                            //make sure we compute slowly
                        BaseDB.Timing        = t;
                        break;
                    }
                }
#endif


                if ((addr.XYZ >= BaseDB.Config.extent).Any)
                {
                    throw new ArgumentOutOfRangeException("addr", addr, "Exceeds extent: " + BaseDB.Config.extent);
                }
                if ((addr < ShardID.Zero).Any)
                {
                    throw new ArgumentOutOfRangeException("addr", addr, "Is (partially) negative");
                }

                Simulation.Run(addr);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
コード例 #29
0
 public static void BeginFetch(ShardID id)
 {
     hostRequests.BeginFetch(HostsStore, id);
 }