/// <summary> /// Runs aggregator /// </summary> /// <param name="cancellationToken">Cancellation token</param> public void Execute(CancellationToken cancellationToken) { Logger.DebugFormat("Aggregating records in 'Counter' table..."); long removedCount = 0; do { using (var storageConnection = (LiteDbConnection)_storage.GetConnection()) { var database = storageConnection.Database; var recordsToAggregate = database .StateDataCounter .FindAll() .Take(NumberOfRecordsInSinglePass) .ToList(); var recordsToMerge = recordsToAggregate .GroupBy(_ => _.Key).Select(_ => new { _.Key, Value = _.Sum(x => x.Value.ToInt64()), ExpireAt = _.Max(x => x.ExpireAt) }); foreach (var id in recordsToAggregate.Select(_ => _.Id)) { database .StateDataCounter .Delete(id); removedCount++; } foreach (var item in recordsToMerge) { AggregatedCounter aggregatedItem = database .StateDataAggregatedCounter .Find(_ => _.Key == item.Key) .FirstOrDefault(); if (aggregatedItem != null) { var aggregatedCounters = database.StateDataAggregatedCounter.Find(_ => _.Key == item.Key); foreach (var counter in aggregatedCounters) { counter.Value = counter.Value.ToInt64() + item.Value; counter.ExpireAt = item.ExpireAt > aggregatedItem.ExpireAt ? (item.ExpireAt.HasValue ? (DateTime?)item.ExpireAt.Value : null) : (aggregatedItem.ExpireAt.HasValue ? (DateTime?)aggregatedItem.ExpireAt.Value : null); database.StateDataAggregatedCounter.Update(counter); } } else { database .StateDataAggregatedCounter .Insert(new AggregatedCounter { Id = ObjectId.NewObjectId(), Key = item.Key, Value = item.Value, ExpireAt = item.ExpireAt }); } } } if (removedCount >= NumberOfRecordsInSinglePass) { cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); cancellationToken.ThrowIfCancellationRequested(); } } while (removedCount >= NumberOfRecordsInSinglePass); cancellationToken.WaitHandle.WaitOne(_interval); }
/// <summary> /// Runs aggregator /// </summary> /// <param name="cancellationToken">Cancellation token</param> public void Execute(CancellationToken cancellationToken) { Logger.DebugFormat("Aggregating records in 'Counter' table..."); long removedCount = 0; do { using (var storageConnection = (HangfireSQLiteConnection)_storage.GetConnection()) { var storageDb = storageConnection.DbContext; var recordsToAggregate = storageDb .CounterRepository .Take(NumberOfRecordsInSinglePass) .ToList(); var recordsToMerge = recordsToAggregate .GroupBy(_ => _.Key).Select(_ => new { _.Key, Value = _.Sum(x => x.Value), ExpireAt = _.Max(x => x.ExpireAt) }); foreach (var id in recordsToAggregate.Select(_ => _.Id)) { storageDb .CounterRepository .Delete(_ => _.Id == id); removedCount++; } foreach (var item in recordsToMerge) { AggregatedCounter aggregatedItem = storageDb .AggregatedCounterRepository .FirstOrDefault(_ => _.Key == item.Key); if (aggregatedItem != null) { var aggregatedCounters = storageDb.AggregatedCounterRepository.Where(_ => _.Key == item.Key).ToList(); foreach (var counter in aggregatedCounters) { counter.Value += item.Value; counter.ExpireAt = item.ExpireAt > aggregatedItem.ExpireAt ? (item.ExpireAt > DateTime.MinValue ? item.ExpireAt : DateTime.MinValue) : (aggregatedItem.ExpireAt > DateTime.MinValue ? aggregatedItem.ExpireAt : DateTime.MinValue); storageDb.Database.Update(counter); } } else { storageDb .Database .Insert(new AggregatedCounter { Key = item.Key, Value = item.Value, ExpireAt = item.ExpireAt }); } } } if (removedCount >= NumberOfRecordsInSinglePass) { cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); cancellationToken.ThrowIfCancellationRequested(); } } while (removedCount >= NumberOfRecordsInSinglePass); cancellationToken.WaitHandle.WaitOne(_interval); }