Ejemplo n.º 1
0
        /// <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);
        }