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); } } }
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."); } } }