protected override async Task RunAsync(CancellationToken cancellationToken) { int hourlyLimit = (int)Math.Round(3600D / HourlyInterval.TotalSeconds); IReliableDictionary <DateTimeOffset, Dictionary <string, long> > dictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <DateTimeOffset, Dictionary <string, long> > >($"history:/hourly"); while (true) { cancellationToken.ThrowIfCancellationRequested(); try { ClusterLoadInformation capacities = await this.query.GetClusterLoadAsync(); DateTimeOffset utcnow = DateTimeOffset.UtcNow; DateTimeOffset timestamp = new DateTimeOffset(utcnow.Year, utcnow.Month, utcnow.Day, utcnow.Hour, utcnow.Minute, utcnow.Second, utcnow.Offset); Dictionary <string, long> values = new Dictionary <string, long>(); foreach (var capacity in capacities.LoadMetricInformationList) { values[capacity.Name] = capacity.ClusterLoad; } using (ITransaction tx = this.StateManager.CreateTransaction()) { long count = await dictionary.GetCountAsync(tx); if (count >= hourlyLimit) { var min = await(await dictionary.CreateLinqAsyncEnumerable(tx)).Min(x => x.Key); await dictionary.TryRemoveAsync(tx, min); } await dictionary.SetAsync(tx, timestamp, values); await tx.CommitAsync(); } } catch (FabricTransientException) { // retry } await Task.Delay(HourlyInterval, cancellationToken); } }
public async Task <IEnumerable <ClusterCapacityHistory> > History(string capacityName, DateTimeOffset startTime) { IReliableDictionary <DateTimeOffset, Dictionary <string, long> > dictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <DateTimeOffset, Dictionary <string, long> > >($"history:/hourly"); using (ITransaction tx = this.stateManager.CreateTransaction()) { return((await dictionary.CreateLinqAsyncEnumerable(tx)) .Where(x => x.Key > startTime) .Select(x => { long capacity; x.Value.TryGetValue(capacityName, out capacity); return new ClusterCapacityHistory(capacity, x.Key); }) .OrderBy(x => x.Timestamp) .ToEnumerable() .ToList()); } }