public async Task IncrementUsage_OnlyChangeCache() { var stack = await _stackRepository.AddAsync(StackData.GenerateStack(id: TestConstants.StackId, projectId: TestConstants.ProjectId, organizationId: TestConstants.OrganizationId), o => o.ImmediateConsistency()); // Assert stack state in elasticsearch before increment usage Assert.Equal(0, stack.TotalOccurrences); Assert.True(stack.FirstOccurrence <= SystemClock.UtcNow); Assert.True(stack.LastOccurrence <= SystemClock.UtcNow); // Assert state in cache before increment usage Assert.Equal(DateTime.MinValue, await _cache.GetUnixTimeMillisecondsAsync(_stackService.GetStackOccurrenceMinDateCacheKey(stack.Id))); Assert.Equal(DateTime.MinValue, await _cache.GetUnixTimeMillisecondsAsync(_stackService.GetStackOccurrenceMaxDateCacheKey(stack.Id))); Assert.Equal(0, await _cache.GetAsync <long>(_stackService.GetStackOccurrenceCountCacheKey(stack.Id), 0)); var occurrenceSet = await _cache.GetListAsync <(string OrganizationId, string ProjectId, string StackId)>(_stackService.GetStackOccurrenceSetCacheKey()); Assert.True(occurrenceSet.IsNull || !occurrenceSet.HasValue || occurrenceSet.Value.Count == 0); var firstUtcNow = SystemClock.UtcNow.Floor(TimeSpan.FromMilliseconds(1)); await RefreshDataAsync(); await _stackService.IncrementStackUsageAsync(TestConstants.OrganizationId, TestConstants.ProjectId, stack.Id, firstUtcNow, firstUtcNow, 1); // Assert stack state has no change after increment usage stack = await _stackRepository.GetByIdAsync(TestConstants.StackId); Assert.Equal(0, stack.TotalOccurrences); Assert.True(stack.FirstOccurrence <= SystemClock.UtcNow); Assert.True(stack.LastOccurrence <= SystemClock.UtcNow); // Assert state in cache has been changed after increment usage Assert.Equal(firstUtcNow, await _cache.GetUnixTimeMillisecondsAsync(_stackService.GetStackOccurrenceMinDateCacheKey(stack.Id))); Assert.Equal(firstUtcNow, await _cache.GetUnixTimeMillisecondsAsync(_stackService.GetStackOccurrenceMaxDateCacheKey(stack.Id))); Assert.Equal(1, await _cache.GetAsync <long>(_stackService.GetStackOccurrenceCountCacheKey(stack.Id), 0)); occurrenceSet = await _cache.GetListAsync <(string OrganizationId, string ProjectId, string StackId)>(_stackService.GetStackOccurrenceSetCacheKey()); Assert.Single(occurrenceSet.Value); var secondUtcNow = SystemClock.UtcNow.Floor(TimeSpan.FromMilliseconds(1)); await RefreshDataAsync(); await _stackService.IncrementStackUsageAsync(TestConstants.OrganizationId, TestConstants.ProjectId, stack.Id, secondUtcNow, secondUtcNow, 2); // Assert state in cache has been changed after increment usage again Assert.Equal(firstUtcNow, await _cache.GetUnixTimeMillisecondsAsync(_stackService.GetStackOccurrenceMinDateCacheKey(stack.Id))); Assert.Equal(secondUtcNow, await _cache.GetUnixTimeMillisecondsAsync(_stackService.GetStackOccurrenceMaxDateCacheKey(stack.Id))); Assert.Equal(3, await _cache.GetAsync <long>(_stackService.GetStackOccurrenceCountCacheKey(stack.Id), 0)); occurrenceSet = await _cache.GetListAsync <(string OrganizationId, string ProjectId, string StackId)>(_stackService.GetStackOccurrenceSetCacheKey()); Assert.Single(occurrenceSet.Value); }
private async Task IncrementEventCountersAsync(IGrouping <string, EventContext> stackGroup) { var stackContexts = stackGroup.ToList(); try { int count = stackContexts.Count; var minDate = stackContexts.Min(s => s.Event.Date.UtcDateTime); var maxDate = stackContexts.Max(s => s.Event.Date.UtcDateTime); await _stackService.IncrementStackUsageAsync(stackContexts[0].Event.OrganizationId, stackContexts[0].Event.ProjectId, stackGroup.Key, minDate, maxDate, count).AnyContext(); // Update stacks in memory since they are used in notifications. foreach (var ctx in stackContexts) { if (ctx.Stack.FirstOccurrence > minDate) { ctx.Stack.FirstOccurrence = minDate; } if (ctx.Stack.LastOccurrence < maxDate) { ctx.Stack.LastOccurrence = maxDate; } ctx.Stack.TotalOccurrences += count; } } catch (Exception ex) { foreach (var context in stackContexts) { bool cont = false; try { cont = HandleError(ex, context); } catch { } if (!cont) { context.SetError(ex.Message, ex); } } } }