示例#1
0
        /// <inheritdoc/>
        public override Task Initialize(string strProviderName, IStreamQueueMapper queueMapper, TimeSpan siloMaturityPeriod)
        {
            if (queueMapper == null)
            {
                throw new ArgumentNullException("queueMapper");
            }
            var options = this.serviceProvider.GetRequiredService <IOptionsSnapshot <LeaseBasedQueueBalancerOptions> >().Get(strProviderName);

            if (options == null)
            {
                throw new KeyNotFoundException($"No lease base queue balancer options was configured for provider {strProviderName}, nor was a default configured.");
            }
            this.leaseProvider      = this.serviceProvider.GetRequiredService(options.LeaseProviderType) as ILeaseProvider;
            this.leaseLength        = options.LeaseLength;
            this.allQueues          = new ReadOnlyCollection <QueueId>(queueMapper.GetAllQueues().ToList());
            this.siloMaturityPeriod = siloMaturityPeriod;
            NotifyAfterStart().Ignore();
            //make lease renew frequency to be every half of lease time, to avoid renew failing due to timing issues, race condition or clock difference.
            var timerLogger = this.loggerFactory.CreateLogger <AsyncTaskSafeTimer>();

            this.renewLeaseTimer = new AsyncTaskSafeTimer(timerLogger, this.MaintainAndBalanceQueues, null, this.siloMaturityPeriod, this.leaseLength.Divide(2));
            //try to acquire maximum leases every leaseLength
            this.tryAcquireMaximumLeaseTimer = new AsyncTaskSafeTimer(timerLogger, this.AcquireLeaseToMeetMaxResponsibilty, null, this.siloMaturityPeriod, this.leaseLength);
            //Selector default to round robin selector now, but we can make a further change to make selector configurable if needed.  Selector algorithm could
            //be affecting queue balancing stablization time in cluster initializing and auto-scaling
            this.queueSelector = new RoundRobinSelector <QueueId>(this.allQueues);
            return(MaintainAndBalanceQueues(null));
        }
示例#2
0
        internal void NextSelectionWontGoInfinitely(List <string> resources, IResourceSelector <string> resourceSelector)
        {
            Assert.Equal(resources.Distinct().Count(), resources.Count);
            resources.Sort();
            List <string> selected = resourceSelector.NextSelection(int.MaxValue, new List <string>());

            Assert.Equal(resources.Count, selected.Count);
            selected = selected.Distinct().ToList();
            selected.Sort();
            Assert.Equal(resources.Count, selected.Count);
            for (int i = 0; i < selected.Count; i++)
            {
                Assert.Equal(resources[i], selected[i]);
            }
        }
        /// <inheritdoc/>
        public override Task Initialize(IStreamQueueMapper queueMapper)
        {
            if (base.Cancellation.IsCancellationRequested)
            {
                throw new InvalidOperationException("Cannot initialize a terminated balancer.");
            }
            if (queueMapper == null)
            {
                throw new ArgumentNullException("queueMapper");
            }
            this.allQueues = new ReadOnlyCollection <QueueId>(queueMapper.GetAllQueues().ToList());

            //Selector default to round robin selector now, but we can make a further change to make selector configurable if needed.  Selector algorithm could
            //be affecting queue balancing stablization time in cluster initializing and auto-scaling
            this.queueSelector = new RoundRobinSelector <QueueId>(this.allQueues, new Random(this.GetHashCode()));
            return(base.Initialize(queueMapper));
        }
        /// <inheritdoc/>
        public override Task Initialize(IStreamQueueMapper queueMapper)
        {
            if (queueMapper == null)
            {
                throw new ArgumentNullException("queueMapper");
            }
            this.allQueues = new ReadOnlyCollection <QueueId>(queueMapper.GetAllQueues().ToList());
            if (this.allQueues.Count == 0)
            {
                return(Task.CompletedTask);
            }
            this.leaseProvider = this.serviceProvider.GetRequiredService(options.LeaseProviderType) as ILeaseProvider;
            NotifyAfterStart().Ignore();
            //make lease renew frequency to be every half of lease time, to avoid renew failing due to timing issues, race condition or clock difference.
            ITimerRegistry timerRegistry = this.serviceProvider.GetRequiredService <ITimerRegistry>();

            this.renewLeaseTimer = timerRegistry.RegisterTimer(null, this.MaintainAndBalanceQueues, null, this.options.SiloMaturityPeriod, this.options.LeaseLength.Divide(2));
            //try to acquire maximum leases every leaseLength
            this.tryAcquireMaximumLeaseTimer = timerRegistry.RegisterTimer(null, this.AcquireLeaseToMeetMaxResponsibility, null, this.options.SiloMaturityPeriod, this.options.SiloMaturityPeriod);
            //Selector default to round robin selector now, but we can make a further change to make selector configurable if needed.  Selector algorithm could
            //be affecting queue balancing stablization time in cluster initializing and auto-scaling
            this.queueSelector = new RoundRobinSelector <QueueId>(this.allQueues);
            return(MaintainAndBalanceQueues(null));
        }
示例#5
0
        /// <summary>
        /// Sets a resource selector for the current CallContext.
        /// </summary>
        /// <param name="resourceSelector">The resource selector to be used in the current CallContext.</param>
        IResourceSelector IHasContextualResourceSelector.SetContextualResourceSelector(IResourceSelector resourceSelector)
        {
            CallContext.SetData(ResourceSelectorKey, resourceSelector);

            return(DefaultResourceSelector);
        }
示例#6
0
 public RoundRobinSelectorTests(ITestOutputHelper output) : base(output)
 {
     this.resources        = Enumerable.Range(0, ResourceCount).Select(i => $"resource_{i}").ToList();
     this.resourceSelector = new RoundRobinSelector <string>(this.resources);
 }
示例#7
0
        internal void NextSelectionWontReSelectExistingSelections(List <string> resources, IResourceSelector <string> resourceSelector)
        {
            Assert.Equal(resources.Distinct().Count(), resources.Count);
            for (int selectCount = 0; selectCount < resources.Count; selectCount++)
            {
                for (int excludeCount = 0; excludeCount < resources.Count; excludeCount++)
                {
                    List <string> excluded = resourceSelector.NextSelection(excludeCount, new List <string>());
                    Assert.Equal(excludeCount, excluded.Count);
                    excluded = excluded.Distinct().ToList();
                    Assert.Equal(excludeCount, excluded.Count);

                    List <string> selected      = resourceSelector.NextSelection(selectCount, excluded);
                    int           expectedCount = Math.Min(selectCount, resources.Count - excludeCount);
                    Assert.Equal(expectedCount, selected.Count);
                    selected = selected.Distinct().ToList();
                    Assert.Equal(expectedCount, selected.Count);
                    for (int i = 0; i < selected.Count; i++)
                    {
                        Assert.DoesNotContain(selected[i], excluded);
                    }
                }
            }
        }
示例#8
0
        internal void NextSelectionWillGoThroughEveryResourceIfExistingSelectionEmpty(List <string> resources, IResourceSelector <string> resourceSelector)
        {
            Assert.Equal(resources.Distinct().Count(), resources.Count);
            resources.Sort();
            List <string> selected = resourceSelector.NextSelection(resources.Count, new List <string>());

            Assert.Equal(resources.Count, selected.Count);
            selected = selected.Distinct().ToList();
            selected.Sort();
            Assert.Equal(resources.Count, selected.Count);
            for (int i = 0; i < selected.Count; i++)
            {
                Assert.Equal(resources[i], selected[i]);
            }
        }