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); }
/// <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); }
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)); }
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))); }
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); }
private int SiloLoad_ByActivations(CachedLocalStat cachedStats) { return(useLocalCache ? cachedStats.ActivationCount + cachedStats.SiloStats.ActivationCount : cachedStats.SiloStats.ActivationCount); }
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)))); }
private int SiloLoad_ByRecentActivations(CachedLocalStat cachedStats) { return useLocalCache ? cachedStats.ActivationCount + cachedStats.SiloStats.RecentlyUsedActivationCount : cachedStats.SiloStats.RecentlyUsedActivationCount; }
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); }