public void Update(IReadOnlyDictionary <Uri, Weight> updatedWeights, RelativeWeightSettings settings) { var newReplicas = new HashSet <Uri>(updatedWeights.Select(p => p.Key)); var newWeights = new Dictionary <Uri, Weight>(updatedWeights.Count); var currentTime = DateTime.UtcNow; foreach (var(currentReplica, currentWeight) in currentWeights) { if (newReplicas.Contains(currentReplica)) { newWeights[currentReplica] = updatedWeights[currentReplica]; newReplicas.Remove(currentReplica); continue; } if (currentTime - currentWeight.Timestamp < settings.WeightsTTL) { newWeights[currentReplica] = ApplyRegenerationIfNeed(currentWeight, settings); } } foreach (var newReplica in newReplicas) { newWeights[newReplica] = updatedWeights[newReplica]; } currentWeights = newWeights; }
private Weight ApplyRegenerationIfNeed(Weight weight, RelativeWeightSettings settings) { var ageMinutes = (DateTime.UtcNow - weight.Timestamp).TotalMinutes; ageMinutes = Math.Max(0, ageMinutes - settings.RegenerationLag.TotalMinutes); var regenerationAmount = Math.Max(0, ageMinutes * settings.RegenerationRatePerMinute); var newValue = Math.Min(1.0, weight.Value + regenerationAmount); return(new Weight(newValue, weight.Timestamp)); }
public RelativeWeightModifier( RelativeWeightSettings settings, string service, string environment, double minWeight = ClusterClientDefaults.MinimumReplicaWeight, double maxWeight = ClusterClientDefaults.MaximumReplicaWeight, IGlobalStorageProvider globalStorageProvider = null, ILog log = null) { this.settings = settings; this.minWeight = minWeight; this.maxWeight = maxWeight; this.log = (log ?? new SilentLog()).ForContext <RelativeWeightModifier>(); this.globalStorageProvider = globalStorageProvider ?? new PerProcessGlobalStorageProvider(); storageKey = CreateStorageKey(service, environment); }