public IList <BandMailboxRebalanceData> LoadBalanceForest(ILoadBalance loadBalancer, bool startMoves, ILogger logger, TimeSpan timeout)
        {
            RebalancingRequestMoveStarter moveStarter = new RebalancingRequestMoveStarter(this.context.ClientFactory, logger, this.context.QueueManager);
            LoadContainer loadTopology = this.context.HeatMap.GetLoadTopology();

            if (this.context.Settings.SoftDeletedCleanupEnabled)
            {
                int softDeletedCleanupThreshold   = this.context.Settings.SoftDeletedCleanupThreshold;
                SoftDeletedCleanUpRequest request = new SoftDeletedCleanUpRequest(loadTopology, this.context.ClientFactory, softDeletedCleanupThreshold, logger);
                this.context.QueueManager.MainProcessingQueue.EnqueueRequest(request);
            }
            long aggregateConsumedLoad = loadTopology.GetAggregateConsumedLoad(InProgressLoadBalancingMoveCount.Instance);

            if (aggregateConsumedLoad > this.context.Settings.MaximumPendingMoveCount)
            {
                logger.LogWarning("Did not start load balancing run because current number of pending moves {0} is greater than MaximumPendingMoveCount {1}", new object[]
                {
                    aggregateConsumedLoad,
                    this.context.Settings.MaximumPendingMoveCount
                });
                return(Array <BandMailboxRebalanceData> .Empty);
            }
            ForestLoadBalanceRequest forestLoadBalanceRequest = new ForestLoadBalanceRequest(loadBalancer, startMoves, logger, moveStarter, loadTopology, new PartitionExtractor());

            this.context.QueueManager.MainProcessingQueue.EnqueueRequest(forestLoadBalanceRequest);
            forestLoadBalanceRequest.WaitExecutionAndThrowOnFailure(timeout);
            return(forestLoadBalanceRequest.Results);
        }
Пример #2
0
        public bool Visit(LoadContainer container)
        {
            if (container.ContainerType != ContainerType.Database)
            {
                return(true);
            }
            LoadMetric         instance           = PhysicalSize.Instance;
            ByteQuantifiedSize sizeMetric         = container.MaximumLoad.GetSizeMetric(instance);
            ByteQuantifiedSize byteQuantifiedSize = sizeMetric * this.threshold / 100;
            ByteQuantifiedSize sizeMetric2        = container.ConsumedLoad.GetSizeMetric(instance);

            this.logger.LogVerbose("Database {0} has maximum physical size {1}, SoftDeletedThreshold of {2}, target size {3}, consumed physical size {4}", new object[]
            {
                container,
                sizeMetric,
                this.threshold,
                byteQuantifiedSize,
                sizeMetric2
            });
            if (sizeMetric2 >= byteQuantifiedSize)
            {
                SoftDeletedDatabaseCleanupRequest request = new SoftDeletedDatabaseCleanupRequest(this.clientFactory, (DirectoryDatabase)container.DirectoryObject, byteQuantifiedSize);
                base.Queue.EnqueueRequest(request);
            }
            return(false);
        }
        public override LoadContainer ExtractTopology()
        {
            LoadContainer loadContainer = this.CreateDatabaseContainer();

            this.ExtractConstraintSetHierarchy(loadContainer);
            return(loadContainer);
        }
Пример #4
0
 public ChildContainerExtractor(DirectoryObject child, LoadContainer loadContainer, ILogger logger, TopologyExtractor extractor)
 {
     this.child          = child;
     this.loadContainer  = loadContainer;
     this.logger         = logger;
     this.childExtractor = extractor;
 }
        private void ExtractConstraintSetHierarchy(LoadContainer databaseContainer)
        {
            DirectoryDatabase directoryDatabase           = (DirectoryDatabase)base.DirectoryObject;
            Dictionary <string, LoadContainer> dictionary = new Dictionary <string, LoadContainer>();

            foreach (DirectoryMailbox directoryMailbox in directoryDatabase.GetMailboxes())
            {
                TopologyExtractor extractor = base.ExtractorFactory.GetExtractor(directoryMailbox);
                IMailboxProvisioningConstraints mailboxProvisioningConstraints = directoryMailbox.MailboxProvisioningConstraints;
                string text = null;
                if (mailboxProvisioningConstraints != null)
                {
                    text = mailboxProvisioningConstraints.HardConstraint.Value;
                }
                text = (text ?? string.Empty);
                if (!dictionary.ContainsKey(text))
                {
                    DirectoryIdentity identity        = new DirectoryIdentity(DirectoryObjectType.ConstraintSet, Guid.NewGuid(), text, directoryMailbox.Identity.OrganizationId);
                    DirectoryObject   directoryObject = new DirectoryObject(base.DirectoryObject.Directory, identity);
                    LoadContainer     value           = new LoadContainer(directoryObject, ContainerType.ConstraintSet);
                    dictionary.Add(text, value);
                    databaseContainer.AddChild(dictionary[text]);
                }
                LoadEntity extractedEntity = extractor.ExtractEntity();
                this.AddEntityToContainer(dictionary[text], extractedEntity);
            }
        }
Пример #6
0
        public override LoadContainer GetLocalServerData(Band[] bands)
        {
            LoadContainer localServerData = base.GetLocalServerData(bands);

            localServerData.ConvertFromSerializationFormat();
            return(localServerData);
        }
Пример #7
0
        public void AddObject(IObjRef objRef, IPrimitiveUpdateItem[] primitiveUpdates, IRelationUpdateItem[] relationUpdates, String changedBy, long changedOn)
        {
            IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(objRef.RealType);

            Object[]    primitives = new Object[metaData.PrimitiveMembers.Length];
            IObjRef[][] relations  = new IObjRef[metaData.RelationMembers.Length][];
            for (int a = relations.Length; a-- > 0;)
            {
                relations[a] = ObjRef.EMPTY_ARRAY;
            }
            LoadContainer loadContainer = new LoadContainer();

            loadContainer.Reference  = new ObjRef(objRef.RealType, objRef.Id, null);
            loadContainer.Primitives = primitives;
            loadContainer.Relations  = relations;

            writeLock.Lock();
            try
            {
                refToObjectDict.Add(loadContainer.Reference, loadContainer);

                ChangeObject(objRef, primitiveUpdates, relationUpdates, changedBy, changedOn);
            }
            finally
            {
                writeLock.Unlock();
            }
        }
Пример #8
0
        private void SetCommittedLoads(LoadContainer root)
        {
            LoadMetricStorage left = new LoadMetricStorage();

            if (root.ContainerType == ContainerType.Database)
            {
                foreach (LoadEntity loadEntity in root.Children)
                {
                    LoadContainer loadContainer = (LoadContainer)loadEntity;
                    left += loadContainer.ConsumedLoad;
                }
                using (List <LoadEntity> .Enumerator enumerator2 = root.Children.GetEnumerator())
                {
                    while (enumerator2.MoveNext())
                    {
                        LoadEntity    loadEntity2    = enumerator2.Current;
                        LoadContainer loadContainer2 = (LoadContainer)loadEntity2;
                        loadContainer2.CommittedLoad = left - loadContainer2.ConsumedLoad;
                    }
                    return;
                }
            }
            foreach (LoadEntity loadEntity3 in root.Children)
            {
                LoadContainer committedLoads = (LoadContainer)loadEntity3;
                this.SetCommittedLoads(committedLoads);
            }
        }
Пример #9
0
        private LoadContainer CopyForConstraint(LoadContainer root, string constraint)
        {
            List <LoadContainer> list = new List <LoadContainer>();

            foreach (LoadEntity loadEntity in root.Children)
            {
                LoadContainer root2         = (LoadContainer)loadEntity;
                LoadContainer loadContainer = this.CopyForConstraint(root2, constraint);
                if (loadContainer != null)
                {
                    list.Add(loadContainer);
                }
            }
            bool flag = this.ShouldCullNode(root, list, constraint);

            if (flag)
            {
                return(null);
            }
            LoadContainer shallowCopy = root.GetShallowCopy();

            foreach (LoadContainer child in list)
            {
                shallowCopy.AddChild(child);
            }
            return(shallowCopy);
        }
Пример #10
0
        private void AggregateDatabase(LoadContainer database)
        {
            BandData bandData = database.ConsumedLoad.GetBandData(this.band);

            bandData.Database = database;
            this.bandData.Add(bandData);
        }
Пример #11
0
        private double GetBandDelta(double weightAverage, double deviation, BandData band)
        {
            LoadContainer database = band.Database;
            double        num      = Math.Round(weightAverage * (double)database.RelativeLoadWeight * (1.0 + deviation));

            return((double)band.TotalWeight - num);
        }
        protected override LoadContainer BuildTopology(TopologyExtractorFactoryContext topologyExtractorContext)
        {
            TopologyExtractorFactory loadBalancingLocalFactory = topologyExtractorContext.GetLoadBalancingLocalFactory(false);
            DirectoryServer          localServer   = base.ServiceContext.Directory.GetLocalServer();
            TopologyExtractor        extractor     = loadBalancingLocalFactory.GetExtractor(localServer);
            LoadContainer            loadContainer = extractor.ExtractTopology();

            ExAssert.RetailAssert(loadContainer != null, "Extracted toplogy for server '{0}' should never be null.", new object[]
            {
                localServer
            });
            DatabaseCollector databaseCollector = new DatabaseCollector();

            loadContainer.Accept(databaseCollector);
            IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(1, TimeSpan.Zero, base.ServiceContext.Logger);

            foreach (LoadContainer loadContainer2 in databaseCollector.Databases)
            {
                DirectoryDatabase directoryDatabase = loadContainer2.DirectoryObject as DirectoryDatabase;
                if (directoryDatabase != null)
                {
                    DatabaseProcessor @object = new DatabaseProcessor(base.ServiceContext.Settings, base.ServiceContext.DrainControl, base.ServiceContext.Logger, directoryDatabase);
                    operationRetryManager.TryRun(new Action(@object.ProcessDatabase));
                }
            }
            return(loadContainer);
        }
Пример #13
0
 public SoftDeletedCleanUpRequest(LoadContainer forestTopology, IClientFactory clientFactory, int threshold, ILogger logger)
 {
     this.forestTopology = forestTopology;
     this.clientFactory  = clientFactory;
     this.threshold      = threshold;
     this.logger         = logger;
 }
Пример #14
0
        public override void Initialize()
        {
            IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(typeof(Material));

            LoadContainer lc = new LoadContainer();

            lc.Reference  = new ObjRef(typeof(Material), 1, 1);
            lc.Primitives = new Object[metaData.PrimitiveMembers.Length];
            lc.Relations  = new IObjRef[metaData.RelationMembers.Length][];

            lc.Primitives[metaData.GetIndexByPrimitiveName("Name")] = "Name1";

            databaseMap.Put(lc.Reference, lc);

            IEntityMetaData metaData2 = EntityMetaDataProvider.GetMetaData(typeof(MaterialType));
            LoadContainer   lc2       = new LoadContainer();

            lc2.Reference  = new ObjRef(typeof(MaterialType), 2, 1);
            lc2.Primitives = new Object[metaData2.PrimitiveMembers.Length];
            lc2.Relations  = new IObjRef[metaData2.RelationMembers.Length][];

            lc2.Primitives[metaData2.GetIndexByPrimitiveName("Name")] = "Name2";

            lc.Relations[metaData.GetIndexByRelationName("Types")] = new IObjRef[] { lc2.Reference };

            databaseMap.Put(lc2.Reference, lc2);
        }
Пример #15
0
        protected virtual void InjectMoves(LoadContainer database, BatchName batchName, IEnumerable <LoadEntity> mailboxes, bool throwIfNotValid)
        {
            IRequestQueue          injectorQueue         = this.queueManager.GetInjectionQueue((DirectoryDatabase)database.DirectoryObject);
            IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(this.logger);

            using (IEnumerator <LoadEntity> enumerator = mailboxes.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    LoadEntity mailbox = enumerator.Current;
                    if (mailbox.DirectoryObject == null)
                    {
                        this.logger.Log(MigrationEventType.Warning, "Not injecting move for {0} because its DirectoryObject is null", new object[]
                        {
                            mailbox
                        });
                    }
                    else
                    {
                        OperationRetryManagerResult operationRetryManagerResult = operationRetryManager.TryRun(delegate
                        {
                            DirectoryObject directoryObject = mailbox.DirectoryObject;
                            ConstraintValidationResult constraintValidationResult = database.Constraint.Accept(mailbox);
                            if (constraintValidationResult.Accepted)
                            {
                                database.CommittedLoad += mailbox.ConsumedLoad;
                                if (directoryObject.SupportsMoving)
                                {
                                    DirectoryObject directoryObject2 = database.DirectoryObject;
                                    IRequest request = directoryObject.CreateRequestToMove(directoryObject2.Identity, batchName.ToString(), this.logger);
                                    injectorQueue.EnqueueRequest(request);
                                    return;
                                }
                                if (throwIfNotValid)
                                {
                                    throw new ObjectCannotBeMovedException(mailbox.DirectoryObjectIdentity.ObjectType.ToString(), mailbox.DirectoryObjectIdentity.ToString());
                                }
                            }
                            else
                            {
                                this.logger.Log(MigrationEventType.Warning, "Not injecting move for {0} because it violates the target database constraints: {1}", new object[]
                                {
                                    mailbox,
                                    constraintValidationResult
                                });
                                if (throwIfNotValid)
                                {
                                    constraintValidationResult.Constraint.ValidateAccepted(mailbox);
                                }
                            }
                        });
                        if (!operationRetryManagerResult.Succeeded && throwIfNotValid)
                        {
                            throw operationRetryManagerResult.Exception;
                        }
                    }
                }
            }
        }
Пример #16
0
 public bool Visit(LoadContainer container)
 {
     if (container.ContainerType == ContainerType.Database)
     {
         this.databases.Add(container);
     }
     return(true);
 }
 public override HeatMapCapacityData GetCapacitySummary(DirectoryIdentity objectIdentity, bool refreshData)
 {
     if (objectIdentity.Equals(base.TargetServer.Identity))
     {
         LoadContainer localServerData = this.GetLocalServerData(this.context.GetActiveBands());
         return(localServerData.ToCapacityData());
     }
     return(base.GetCapacitySummary(objectIdentity, refreshData));
 }
Пример #18
0
        public void ProcessRebalanceRequest(BandMailboxRebalanceData rebalanceRequest)
        {
            AnchorUtil.ThrowOnNullArgument(rebalanceRequest, "rebalanceRequest");
            BandRebalanceRequest request         = new BandRebalanceRequest(rebalanceRequest, this.clientFactory, this.logger);
            LoadContainer        sourceDatabase  = rebalanceRequest.SourceDatabase;
            IRequestQueue        processingQueue = this.GetProcessingQueue(sourceDatabase);

            processingQueue.EnqueueRequest(request);
        }
Пример #19
0
 public bool Visit(LoadContainer container)
 {
     if (container.ContainerType != ContainerType.Database)
     {
         return(container.CanAcceptRegularLoad);
     }
     this.AggregateDatabase(container);
     return(false);
 }
Пример #20
0
 public LoadContainer GetLocalServerData(Band[] bands)
 {
     return(base.CallService <LoadContainer>(delegate()
     {
         LoadContainer localServerData = this.Channel.GetLocalServerData(bands);
         localServerData.Accept(new DirectoryReconnectionVisitor(this.directory, this.Logger));
         return localServerData;
     }));
 }
Пример #21
0
        public DistributedApplicationDataContainer(
            string name = "Temporary",
            DistributedApplicationDataLocality locality = DistributedApplicationDataLocality.Temporary)
        {
            Name     = name;
            Locality = locality;

            LoadContainer?.Invoke(name, locality, this);
        }
Пример #22
0
        private HeatMapCapacityData GetDagCapacityDatum(DirectoryIdentity objectIdentity)
        {
            TopologyExtractorFactoryContext    topologyExtractorFactoryContext = this.serviceContext.GetTopologyExtractorFactoryContext();
            DirectoryDatabaseAvailabilityGroup directoryObject             = (DirectoryDatabaseAvailabilityGroup)this.serviceContext.Directory.GetDirectoryObject(objectIdentity);
            TopologyExtractorFactory           loadBalancingCentralFactory = topologyExtractorFactoryContext.GetLoadBalancingCentralFactory();
            LoadContainer loadContainer = loadBalancingCentralFactory.GetExtractor(directoryObject).ExtractTopology();

            return(loadContainer.ToCapacityData());
        }
Пример #23
0
        protected override LoadContainer BuildTopology(TopologyExtractorFactoryContext topologyExtractorContext)
        {
            TopologyExtractorFactory loadBalancingCentralFactory = topologyExtractorContext.GetLoadBalancingCentralFactory();
            TopologyExtractor        extractor     = loadBalancingCentralFactory.GetExtractor(base.ServiceContext.Directory.GetLocalForest());
            LoadContainer            loadContainer = extractor.ExtractTopology();

            ExAssert.RetailAssert(loadContainer != null, "Extracted toplogy for the forest should never be null.");
            return(loadContainer);
        }
Пример #24
0
        public override EntitySelector GetSelector(LoadContainer container, string constraintSetIdentity, long units)
        {
            if (this.Profile == Band.BandProfile.CountBased)
            {
                return(new NumberOfEntitiesSelector(this, units, container, constraintSetIdentity));
            }
            double num = (double)units * this.MailboxSizeWeightFactor;

            return(new TotalSizeEntitySelector(this, ByteQuantifiedSize.FromMB((ulong)num), container, constraintSetIdentity));
        }
Пример #25
0
 public LoadContainer GetLocalServerData(Band[] bands)
 {
     return(base.ForwardExceptions <LoadContainer>(delegate()
     {
         this.serviceContext.LocalServerHeatMap.UpdateBands(bands);
         LoadContainer loadTopology = this.serviceContext.LocalServerHeatMap.GetLoadTopology();
         bool convertBandToBandData = !this.ClientVersion[3];
         return (LoadContainer)loadTopology.ToSerializationFormat(convertBandToBandData);
     }));
 }
        private LoadContainer CreateDatabaseContainer()
        {
            DirectoryDatabase directoryDatabase = (DirectoryDatabase)base.DirectoryObject;
            LoadContainer     loadContainer     = directoryDatabase.ToLoadContainer();

            loadContainer.Constraint = new AllAcceptConstraint(new IAllocationConstraint[]
            {
                loadContainer.Constraint,
                new SpecialMailboxPlacementConstraint(this.nonMovableOrganizations)
            });
            return(loadContainer);
        }
Пример #27
0
        public void InjectMovesOnCompatibilityMode(LoadContainer targetDatabase, BatchName batchName, IEnumerable <LoadEntity> mailboxes, bool throwIfNotValid)
        {
            IList <LoadEntity> list = (mailboxes as IList <LoadEntity>) ?? mailboxes.ToList <LoadEntity>();

            this.logger.Log(MigrationEventType.Information, "Injecting {0} moves into database '{1}' with batch name '{2}' in backwards compatibility mode.", new object[]
            {
                list.Count,
                targetDatabase.Guid,
                batchName
            });
            this.InjectMoves(targetDatabase, batchName, list, throwIfNotValid);
        }
Пример #28
0
 private IRequestQueue GetProcessingQueue(LoadContainer container)
 {
     if (container.Parent == null)
     {
         return(this.queueManager.GetProcessingQueue(container));
     }
     if (container.DirectoryObjectIdentity.ObjectType == DirectoryObjectType.DatabaseAvailabilityGroup)
     {
         return(this.queueManager.GetProcessingQueue(container));
     }
     return(this.GetProcessingQueue(container.Parent));
 }
Пример #29
0
        public IEnumerable <BandMailboxRebalanceData> BalanceForest(LoadContainer forest)
        {
            IEnumerable <BandMailboxRebalanceData> result;

            try
            {
                this.logger.Log(MigrationEventType.Information, "Starting a new load balancing procedure using the band algorithm.", new object[0]);
                this.results = new List <BandMailboxRebalanceData>();
                this.logger.Log(MigrationEventType.Verbose, "Using {0} bands for balancing.", new object[]
                {
                    this.bands.Count
                });
                this.logger.Log(MigrationEventType.Verbose, "Calculating total database weight in the forest.", new object[0]);
                DatabaseWeightAggregator databaseWeightAggregator = new DatabaseWeightAggregator();
                forest.Accept(databaseWeightAggregator);
                this.logger.Log(MigrationEventType.Verbose, "Forest has a '{0}' total database weight.", new object[]
                {
                    databaseWeightAggregator.TotalWeight
                });
                this.totalDataSelectedToMove = new ByteQuantifiedSize(0UL);
                foreach (Band band in this.bands)
                {
                    BandDataAggregator bandDataAggregator = new BandDataAggregator(band);
                    forest.Accept(bandDataAggregator);
                    this.BalanceBand(band, (double)databaseWeightAggregator.TotalWeight, bandDataAggregator.BandData.ToArray <BandData>());
                }
                ByteQuantifiedSize byteQuantifiedSize = ByteQuantifiedSize.FromGB((ulong)this.settings.MaximumBatchSizeGb);
                ByteQuantifiedSize totalBatchSize     = this.GetTotalBatchSize();
                if (totalBatchSize > byteQuantifiedSize)
                {
                    this.logger.LogWarning("Total selected size is {0}, but we're only allowed to rebalance {1}. Reducing batch.", new object[]
                    {
                        totalBatchSize,
                        byteQuantifiedSize
                    });
                    IBatchSizeReducer batchSizeReducer = BatchSizeReducerFactory.Instance.GetBatchSizeReducer(byteQuantifiedSize, totalBatchSize, this.logger);
                    result = batchSizeReducer.ReduceBatchSize(this.results);
                }
                else
                {
                    result = this.results;
                }
            }
            finally
            {
                this.logger.Log(MigrationEventType.Information, "Finished load balancing procedure using the band algorithm. {0} rebalancing entries created.", new object[]
                {
                    this.results.Count
                });
            }
            return(result);
        }
 public bool Visit(LoadContainer container)
 {
     if (container.ContainerType != ContainerType.Database)
     {
         return(container.CanAcceptRegularLoad);
     }
     if (!container.CanAcceptRegularLoad)
     {
         return(false);
     }
     this.TotalWeight += container.RelativeLoadWeight;
     return(false);
 }