protected async Task MembershipTable_GetGateways()
        {
            var membershipEntries = Enumerable.Range(0, 10).Select(i => CreateMembershipEntryForTest()).ToArray();

            membershipEntries[3].Status    = SiloStatus.Active;
            membershipEntries[3].ProxyPort = 0;
            membershipEntries[5].Status    = SiloStatus.Active;
            membershipEntries[9].Status    = SiloStatus.Active;

            var data = await membershipTable.ReadAll();

            Assert.NotNull(data);
            Assert.Equal(0, data.Members.Count);

            var version = data.Version;

            foreach (var membershipEntry in membershipEntries)
            {
                Assert.True(await membershipTable.InsertRow(membershipEntry, version));
                version = (await membershipTable.ReadRow(membershipEntry.SiloAddress)).Version;
            }

            var gateways = await gatewayListProvider.GetGateways();

            var entries = new List <string>(gateways.Select(g => g.ToString()));

            // only members with a non-zero Gateway port
            Assert.DoesNotContain(membershipEntries[3].SiloAddress.ToGatewayUri().ToString(), entries);

            // only Active members
            Assert.Contains(membershipEntries[5].SiloAddress.ToGatewayUri().ToString(), entries);
            Assert.Contains(membershipEntries[9].SiloAddress.ToGatewayUri().ToString(), entries);
            Assert.Equal(2, entries.Count);
        }
Exemple #2
0
        internal async Task RefreshSnapshotLiveGateways_TimerCallback(object context)
        {
            try
            {
                if (gatewayListProvider is null)
                {
                    return;
                }

                // the listProvider.GetGateways() is not under lock.
                var allGateways = await gatewayListProvider.GetGateways();

                var refreshedGateways = allGateways.Select(gw => gw.ToGatewayAddress()).ToList();
                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.LogDebug("Discovered {GatewayCount} gateways: {Gateways}", refreshedGateways.Count, Utils.EnumerableToString(refreshedGateways));
                }

                await UpdateLiveGatewaysSnapshot(refreshedGateways, gatewayListProvider.MaxStaleness);
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.ProxyClient_GetGateways, "Exception occurred during RefreshSnapshotLiveGateways_TimerCallback -> listProvider.GetGateways()", exc);
            }
        }
        protected void Test_GatewaySelection(IGatewayListProvider listProvider)
        {
            IList <Uri> gatewayUris = listProvider.GetGateways().GetResult();

            Assert.True(gatewayUris.Count > 0, $"Found some gateways. Data = {Utils.EnumerableToString(gatewayUris)}");

            var gatewayEndpoints = gatewayUris.Select(uri =>
            {
                return(new IPEndPoint(IPAddress.Parse(uri.Host), uri.Port));
            }).ToList();

            var cfg = new ClientConfiguration
            {
                Gateways = gatewayEndpoints
            };
            var gatewayOptions = new GatewayOptions()
            {
                GatewayListRefreshPeriod = cfg.GatewayListRefreshPeriod,
                PreferedGatewayIndex     = cfg.PreferedGatewayIndex
            };
            var gatewayManager = new GatewayManager(gatewayOptions, listProvider, NullLoggerFactory.Instance);

            var counts = new int[4];

            for (int i = 0; i < 2300; i++)
            {
                var ip   = gatewayManager.GetLiveGateway();
                var addr = IPAddress.Parse(ip.Host);
                Assert.Equal(IPAddress.Loopback, addr);  // "Incorrect IP address returned for gateway"
                Assert.True((0 < ip.Port) && (ip.Port < 5), "Incorrect IP port returned for gateway");
                counts[ip.Port - 1]++;
            }

            // The following needed to be changed as the gateway manager now round-robins through the available gateways, rather than
            // selecting randomly based on load numbers.
            //Assert.True((500 < counts[0]) && (counts[0] < 1500), "Gateway selection is incorrectly skewed");
            //Assert.True((500 < counts[1]) && (counts[1] < 1500), "Gateway selection is incorrectly skewed");
            //Assert.True((125 < counts[2]) && (counts[2] < 375), "Gateway selection is incorrectly skewed");
            //Assert.True((25 < counts[3]) && (counts[3] < 75), "Gateway selection is incorrectly skewed");
            //Assert.True((287 < counts[0]) && (counts[0] < 1150), "Gateway selection is incorrectly skewed");
            //Assert.True((287 < counts[1]) && (counts[1] < 1150), "Gateway selection is incorrectly skewed");
            //Assert.True((287 < counts[2]) && (counts[2] < 1150), "Gateway selection is incorrectly skewed");
            //Assert.True((287 < counts[3]) && (counts[3] < 1150), "Gateway selection is incorrectly skewed");

            int low = 2300 / 4;
            int up  = 2300 / 4;

            Assert.True((low <= counts[0]) && (counts[0] <= up), "Gateway selection is incorrectly skewed. " + counts[0]);
            Assert.True((low <= counts[1]) && (counts[1] <= up), "Gateway selection is incorrectly skewed. " + counts[1]);
            Assert.True((low <= counts[2]) && (counts[2] <= up), "Gateway selection is incorrectly skewed. " + counts[2]);
            Assert.True((low <= counts[3]) && (counts[3] <= up), "Gateway selection is incorrectly skewed. " + counts[3]);
        }
Exemple #4
0
        public GatewayManager(
            IOptions <GatewayOptions> gatewayOptions,
            IGatewayListProvider gatewayListProvider,
            ILoggerFactory loggerFactory,
            ConnectionManager connectionManager)
        {
            this.gatewayOptions = gatewayOptions.Value;
            knownDead           = new Dictionary <SiloAddress, DateTime>();
            rand                        = new SafeRandom();
            logger                      = loggerFactory.CreateLogger <GatewayManager>();
            this.loggerFactory          = loggerFactory;
            this.connectionManager      = connectionManager;
            lockable                    = new object();
            gatewayRefreshCallInitiated = false;

            ListProvider = gatewayListProvider;

            var knownGateways = ListProvider.GetGateways().GetAwaiter().GetResult();

            if (knownGateways.Count == 0)
            {
                string gatewayProviderType = gatewayListProvider.GetType().FullName;
                string err = $"Could not find any gateway in {gatewayProviderType}. Orleans client cannot initialize.";
                logger.Error(ErrorCode.GatewayManager_NoGateways, err);
                throw new OrleansException(err);
            }

            logger.Info(ErrorCode.GatewayManager_FoundKnownGateways, "Found {0} knownGateways from Gateway listProvider {1}", knownGateways.Count, Utils.EnumerableToString(knownGateways));

            if (ListProvider is IGatewayListObservable)
            {
                ((IGatewayListObservable)ListProvider).SubscribeToGatewayNotificationEvents(this);
            }

            roundRobinCounter = this.gatewayOptions.PreferedGatewayIndex >= 0 ? this.gatewayOptions.PreferedGatewayIndex : rand.Next(knownGateways.Count);

            this.knownGateways = cachedLiveGateways = knownGateways.Select(gw => gw.ToGatewayAddress()).ToList();

            lastRefreshTime     = DateTime.UtcNow;
            gatewayRefreshTimer = new AsyncTaskSafeTimer(
                this.loggerFactory.CreateLogger <SafeTimer>(),
                RefreshSnapshotLiveGateways_TimerCallback,
                null,
                this.gatewayOptions.GatewayListRefreshPeriod,
                this.gatewayOptions.GatewayListRefreshPeriod);
        }
Exemple #5
0
        internal async Task RefreshSnapshotLiveGateways_TimerCallback(object context)
        {
            try
            {
                if (gatewayListProvider is null)
                {
                    return;
                }

                // the listProvider.GetGateways() is not under lock.
                var allGateways = await gatewayListProvider.GetGateways();

                var refreshedGateways = allGateways.Select(gw => gw.ToGatewayAddress()).ToList();

                await UpdateLiveGatewaysSnapshot(refreshedGateways, gatewayListProvider.MaxStaleness);
            }
            catch (Exception exc)
            {
                logger.LogError((int)ErrorCode.ProxyClient_GetGateways, exc, "Exception occurred during RefreshSnapshotLiveGateways_TimerCallback -> listProvider.GetGateways()");
            }
        }
Exemple #6
0
        public GatewayManager(ClientConfiguration cfg, IGatewayListProvider gatewayListProvider, ILoggerFactory loggerFactory)
        {
            config                      = cfg;
            knownDead                   = new Dictionary <Uri, DateTime>();
            rand                        = new SafeRandom();
            logger                      = loggerFactory.CreateLogger <GatewayManager>();
            this.loggerFactory          = loggerFactory;
            lockable                    = new object();
            gatewayRefreshCallInitiated = false;

            ListProvider = gatewayListProvider;

            var knownGateways = ListProvider.GetGateways().GetResult();

            if (knownGateways.Count == 0)
            {
                string gatewayProviderType = gatewayListProvider.GetType().FullName;
                string err = String.Format("Could not find any gateway in {0}. Orleans client cannot initialize.", gatewayProviderType);
                logger.Error(ErrorCode.GatewayManager_NoGateways, err);
                throw new OrleansException(err);
            }

            logger.Info(ErrorCode.GatewayManager_FoundKnownGateways, "Found {0} knownGateways from Gateway listProvider {1}", knownGateways.Count, Utils.EnumerableToString(knownGateways));

            if (ListProvider is IGatewayListObservable)
            {
                ((IGatewayListObservable)ListProvider).SubscribeToGatewayNotificationEvents(this);
            }

            roundRobinCounter = cfg.PreferedGatewayIndex >= 0 ? cfg.PreferedGatewayIndex : rand.Next(knownGateways.Count);

            cachedLiveGateways = knownGateways;

            lastRefreshTime = DateTime.UtcNow;
            if (ListProvider.IsUpdatable)
            {
                gatewayRefreshTimer = new SafeTimer(this.loggerFactory.CreateLogger <SafeTimer>(), RefreshSnapshotLiveGateways_TimerCallback, null, config.GatewayListRefreshPeriod, config.GatewayListRefreshPeriod);
            }
        }
Exemple #7
0
        public GatewayManager(ClientConfiguration cfg, IGatewayListProvider gatewayListProvider)
        {
            config = cfg;
            knownDead = new Dictionary<Uri, DateTime>();
            rand = new SafeRandom();
            logger = TraceLogger.GetLogger("Messaging.GatewayManager", TraceLogger.LoggerType.Runtime);
            lockable = new object();
            gatewayRefreshCallInitiated = false;

            ListProvider = gatewayListProvider;

            var knownGateways = ListProvider.GetGateways().GetResult();

            if (knownGateways.Count == 0)
            {
                string gatewayProviderType = gatewayListProvider.GetType().FullName;
                string err = String.Format("Could not find any gateway in {0}. Orleans client cannot initialize.", gatewayProviderType);
                logger.Error(ErrorCode.GatewayManager_NoGateways, err);
                throw new OrleansException(err);
            }

            logger.Info(ErrorCode.GatewayManager_FoundKnownGateways, "Found {0} knownGateways from Gateway listProvider {1}", knownGateways.Count, Utils.EnumerableToString(knownGateways));

            if (ListProvider is IGatewayListObservable)
            {
                ((IGatewayListObservable)ListProvider).SubscribeToGatewayNotificationEvents(this);
            }

            roundRobinCounter = cfg.PreferedGatewayIndex >= 0 ? cfg.PreferedGatewayIndex : rand.Next(knownGateways.Count);

            cachedLiveGateways = knownGateways;

            lastRefreshTime = DateTime.UtcNow;
            if (ListProvider.IsUpdatable)
            {
                gatewayRefreshTimer = new SafeTimer(RefreshSnapshotLiveGateways_TimerCallback, null, config.GatewayListRefreshPeriod, config.GatewayListRefreshPeriod);
            }
        }
Exemple #8
0
        internal void RefreshSnapshotLiveGateways_TimerCallback(object context)
        {
            try
            {
                if (ListProvider == null || !ListProvider.IsUpdatable)
                {
                    return;
                }

                // the listProvider.GetGateways() is not under lock.
                var currentKnownGateways = ListProvider.GetGateways().GetResult();
                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug("Found {0} knownGateways from Gateway listProvider {1}", currentKnownGateways.Count, Utils.EnumerableToString(currentKnownGateways));
                }

                // the next one will grab the lock.
                UpdateLiveGatewaysSnapshot(currentKnownGateways, ListProvider.MaxStaleness);
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.ProxyClient_GetGateways, "Exception occurred during RefreshSnapshotLiveGateways_TimerCallback -> listProvider.GetGateways()", exc);
            }
        }
Exemple #9
0
        internal void RefreshSnapshotLiveGateways_TimerCallback(object context)
        {
            try
            {
                if (ListProvider == null || !ListProvider.IsUpdatable)
                {
                    return;
                }

                // the listProvider.GetGateways() is not under lock.
                var refreshedGateways = ListProvider.GetGateways().GetResult().Select(gw => gw.ToSiloAddress()).ToList();
                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.LogDebug("Discovered {GatewayCount} gateways: {Gateways}", refreshedGateways.Count, Utils.EnumerableToString(refreshedGateways));
                }

                // the next one will grab the lock.
                UpdateLiveGatewaysSnapshot(refreshedGateways, ListProvider.MaxStaleness);
            }
            catch (Exception exc)
            {
                logger.Error(ErrorCode.ProxyClient_GetGateways, "Exception occurred during RefreshSnapshotLiveGateways_TimerCallback -> listProvider.GetGateways()", exc);
            }
        }
Exemple #10
0
        private void Test_GatewaySelection(IGatewayListProvider listProvider)
        {
            IList<Uri> gatewayUris = listProvider.GetGateways().GetResult();
            Assert.IsTrue(gatewayUris.Count > 0, "Found some gateways. Data = {0}", Utils.EnumerableToString(gatewayUris));

            var gatewayEndpoints = gatewayUris.Select(uri =>
            {
                return new IPEndPoint(IPAddress.Parse(uri.Host), uri.Port);
            }).ToList();

            var cfg = new ClientConfiguration
            {
                Gateways = gatewayEndpoints
            };
            var gatewayManager = new GatewayManager(cfg, listProvider);

            var counts = new int[4];

            for (int i = 0; i < 2300; i++)
            {
                var ip = gatewayManager.GetLiveGateway();
                var addr = IPAddress.Parse(ip.Host);
                Assert.AreEqual(IPAddress.Loopback, addr, "Incorrect IP address returned for gateway");
                Assert.IsTrue((0 < ip.Port) && (ip.Port < 5), "Incorrect IP port returned for gateway");
                counts[ip.Port - 1]++;
            }

            // The following needed to be changed as the gateway manager now round-robins through the available gateways, rather than
            // selecting randomly based on load numbers.
            //Assert.IsTrue((500 < counts[0]) && (counts[0] < 1500), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((500 < counts[1]) && (counts[1] < 1500), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((125 < counts[2]) && (counts[2] < 375), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((25 < counts[3]) && (counts[3] < 75), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((287 < counts[0]) && (counts[0] < 1150), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((287 < counts[1]) && (counts[1] < 1150), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((287 < counts[2]) && (counts[2] < 1150), "Gateway selection is incorrectly skewed");
            //Assert.IsTrue((287 < counts[3]) && (counts[3] < 1150), "Gateway selection is incorrectly skewed");

            int low = 2300 / 4;
            int up = 2300 / 4;
            Assert.IsTrue((low <= counts[0]) && (counts[0] <= up), "Gateway selection is incorrectly skewed. " + counts[0]);
            Assert.IsTrue((low <= counts[1]) && (counts[1] <= up), "Gateway selection is incorrectly skewed. " + counts[1]);
            Assert.IsTrue((low <= counts[2]) && (counts[2] <= up), "Gateway selection is incorrectly skewed. " + counts[2]);
            Assert.IsTrue((low <= counts[3]) && (counts[3] <= up), "Gateway selection is incorrectly skewed. " + counts[3]);
        }