コード例 #1
0
        public void SiloStatisticsChangeNotification(SiloAddress updatedSilo, SiloRuntimeStatistics newSiloStats)
        {
            // just create a new empty CachedLocalStat and throw the old one.
            var updatedCacheEntry = new CachedLocalStat(updatedSilo, newSiloStats);

            localCache.AddOrUpdate(updatedSilo, k => updatedCacheEntry, (k, v) => updatedCacheEntry);
        }
コード例 #2
0
        /// <summary>
        /// Selects the best match from list of silos, updates local statistics.
        /// </summary>
        /// <note>
        /// This is equivalent with SelectSiloPowerOfK() with chooseHowMany = #Silos
        /// </note>
        private Task <PlacementResult> SelectSiloGreedy(PlacementStrategy strategy, GrainId grain, IPlacementContext context)
        {
            int             minLoad       = int.MaxValue;
            CachedLocalStat minLoadedSilo = null;

            foreach (CachedLocalStat current in localCache.Values)
            {
                if (IsSiloOverloaded(current.SiloStats))
                {
                    continue;
                }

                int load = SiloLoad_ByRecentActivations(current);
                if (load >= minLoad)
                {
                    continue;
                }

                minLoadedSilo = current;
                minLoad       = load;
            }

            if (minLoadedSilo != null)
            {
                return(MakePlacement(strategy, grain, context, minLoadedSilo));
            }

            var debugLog = string.Format("Unable to select a candidate from {0} silos: {1}", localCache.Count,
                                         Utils.EnumerableToString(
                                             localCache,
                                             kvp => String.Format("SiloAddress = {0} -> {1}", kvp.Key.ToString(), kvp.Value.ToString())));

            logger.Warn(ErrorCode.Placement_ActivationCountBasedDirector_NoSilos, debugLog);
            throw new OrleansException(debugLog);
        }
コード例 #3
0
        private Task <SiloAddress> MakePlacement(CachedLocalStat minLoadedSilo)
        {
            // Increment placement by number of silos instead of by one.
            // This is our trick to get more balanced placement, accounting to the probable
            // case when multiple silos place on the same silo at the same time, before stats are refreshed.
            minLoadedSilo.IncrementActivationCount(localCache.Count);

            return(Task.FromResult(minLoadedSilo.Address));
        }
コード例 #4
0
        private Task<PlacementResult> MakePlacement(PlacementStrategy strategy, GrainId grain, IPlacementContext context, CachedLocalStat minLoadedSilo)
        {
            // Increment placement by number of silos instead of by one.
            // This is our trick to get more balanced placement, accounting to the probable
            // case when multiple silos place on the same silo at the same time, before stats are refreshed.
            minLoadedSilo.IncrementActivationCount(localCache.Count);

            return Task.FromResult(PlacementResult.SpecifyCreation(
                minLoadedSilo.Address,
                strategy,
                context.GetGrainTypeName(grain)));
        }
コード例 #5
0
        public Task <SiloAddress> SelectSiloPowerOfK(PlacementStrategy strategy, PlacementTarget target, IPlacementContext context)
        {
            var compatibleSilos = context.GetCompatibleSilos(target);
            // Exclude overloaded and non-compatible silos
            var relevantSilos = new List <CachedLocalStat>();

            foreach (CachedLocalStat current in localCache.Values)
            {
                if (IsSiloOverloaded(current.SiloStats))
                {
                    continue;
                }
                if (!compatibleSilos.Contains(current.Address))
                {
                    continue;
                }

                relevantSilos.Add(current);
            }

            if (relevantSilos.Count > 0)
            {
                int chooseFrom           = Math.Min(relevantSilos.Count, chooseHowMany);
                var chooseFromThoseSilos = new List <CachedLocalStat>();
                while (chooseFromThoseSilos.Count < chooseFrom)
                {
                    int index      = ThreadSafeRandom.Next(relevantSilos.Count);
                    var pickedSilo = relevantSilos[index];
                    relevantSilos.RemoveAt(index);
                    chooseFromThoseSilos.Add(pickedSilo);
                }

                CachedLocalStat minLoadedSilo = chooseFromThoseSilos.First();
                foreach (CachedLocalStat s in chooseFromThoseSilos)
                {
                    if (SiloLoad_ByRecentActivations(s) < SiloLoad_ByRecentActivations(minLoadedSilo))
                    {
                        minLoadedSilo = s;
                    }
                }

                return(MakePlacement(minLoadedSilo));
            }

            var debugLog = string.Format("Unable to select a candidate from {0} silos: {1}", localCache.Count,
                                         Utils.EnumerableToString(
                                             localCache,
                                             kvp => String.Format("SiloAddress = {0} -> {1}", kvp.Key.ToString(), kvp.Value.ToString())));

            logger.Warn(ErrorCode.Placement_ActivationCountBasedDirector_NoSilos, debugLog);
            throw new OrleansException(debugLog);
        }
コード例 #6
0
 private int SiloLoad_ByActivations(CachedLocalStat cachedStats)
 {
     return(useLocalCache ?
            cachedStats.ActivationCount + cachedStats.SiloStats.ActivationCount :
            cachedStats.SiloStats.ActivationCount);
 }
コード例 #7
0
        private Task <PlacementResult> MakePlacement(PlacementStrategy strategy, GrainId grain, IPlacementContext context, CachedLocalStat minLoadedSilo)
        {
            // Increment placement by number of silos instead of by one.
            // This is our trick to get more balanced placement, accounting to the probable
            // case when multiple silos place on the same silo at the same time, before stats are refreshed.
            minLoadedSilo.IncrementActivationCount(localCache.Count);

            return(Task.FromResult(PlacementResult.SpecifyCreation(
                                       minLoadedSilo.Address,
                                       strategy,
                                       context.GetGrainTypeName(grain))));
        }
コード例 #8
0
 private int SiloLoad_ByRecentActivations(CachedLocalStat cachedStats)
 {
     return useLocalCache ?
         cachedStats.ActivationCount + cachedStats.SiloStats.RecentlyUsedActivationCount :
         cachedStats.SiloStats.RecentlyUsedActivationCount;
 }
コード例 #9
0
 public void SiloStatisticsChangeNotification(SiloAddress updatedSilo, SiloRuntimeStatistics newSiloStats)
 {
     // just create a new empty CachedLocalStat and throw the old one.
     var updatedCacheEntry = new CachedLocalStat(updatedSilo, newSiloStats);
     localCache.AddOrUpdate(updatedSilo, k => updatedCacheEntry, (k, v) => updatedCacheEntry);
 }