public async Task <bool> CanBeAggregatedByAsync(ParsedIncident input, TAggregationEntity aggregationEntity)
        {
            using (_logger.Scope("Determining if entity can be linked to aggregation {AggregationRowKey}", aggregationEntity.RowKey))
            {
                if (!_table.GetChildEntities <TChildEntity, TAggregationEntity>(aggregationEntity).ToList().Any())
                {
                    // A manually created aggregation will have no children. We cannot use an aggregation that was manually created.
                    // It is also possible that some bug or data issue has broken this aggregation. If that is the case, we cannot use it either.
                    _logger.LogInformation("Cannot link entity to aggregation because it is not linked to any children.");
                    return(false);
                }

                // To guarantee that the aggregation reflects the latest information and is actually active, we must update it.
                await _aggregationUpdater.UpdateAsync(aggregationEntity, input.StartTime);

                if (!aggregationEntity.IsActive && input.IsActive)
                {
                    _logger.LogInformation("Cannot link entity to aggregation because it has been deactivated and the incident has not been.");
                    return(false);
                }

                _logger.LogInformation("Entity can be linked to aggregation.");
                return(true);
            }
        }
 public async Task UpdateAllAsync(DateTime cursor)
 {
     using (_logger.Scope("Updating active events."))
     {
         var activeEvents = _table.GetActiveEntities <EventEntity>().ToList();
         _logger.LogInformation("Updating {ActiveEventsCount} active events.", activeEvents.Count());
         foreach (var activeEvent in activeEvents)
         {
             await _updater.UpdateAsync(activeEvent, cursor);
         }
     }
 }
Beispiel #3
0
        public async Task UpdateAsync(TAggregationEntity aggregationEntity, DateTime cursor)
        {
            aggregationEntity = aggregationEntity ?? throw new ArgumentNullException(nameof(aggregationEntity));

            using (_logger.Scope("Updating aggregation {AggregationRowKey} given cursor {Cursor}.", aggregationEntity.RowKey, cursor))
            {
                if (!aggregationEntity.IsActive)
                {
                    _logger.LogInformation("Aggregation is inactive, cannot update.");
                    return;
                }

                var hasActiveOrRecentChildren = false;
                var children = _table
                               .GetChildEntities <TChildEntity, TAggregationEntity>(aggregationEntity)
                               .ToList();

                if (children.Any())
                {
                    _logger.LogInformation("Aggregation has {ChildrenCount} children. Updating each child.", children.Count);
                    foreach (var child in children)
                    {
                        await _aggregatedEntityUpdater.UpdateAsync(child, cursor);

                        hasActiveOrRecentChildren =
                            hasActiveOrRecentChildren ||
                            child.IsActive ||
                            child.EndTime > cursor - _groupEndDelay;
                    }
                }
                else
                {
                    _logger.LogInformation("Aggregation has no children and must have been created manually, cannot update.");
                    return;
                }

                if (!hasActiveOrRecentChildren)
                {
                    _logger.LogInformation("Deactivating aggregation because its children are inactive and too old.");
                    var lastEndTime = children.Max(i => i.EndTime.Value);
                    aggregationEntity.EndTime = lastEndTime;

                    await _table.ReplaceAsync(aggregationEntity);
                }
                else
                {
                    _logger.LogInformation("Aggregation has active or recent children so it will not be deactivated.");
                }
            }
        }