Esempio n. 1
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)
 {
 }
Esempio n. 2
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();
        }
Esempio n. 3
0
        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);
            }
        }