Esempio n. 1
0
        private async Task <Dictionary <string, double> > GetUserCountByProjectIdsAsync(ICollection <Stack> stacks, string systemFilter, DateTime utcStart, DateTime utcEnd)
        {
            var scopedCacheClient = new ScopedCacheClient(_cacheClient, $"project:user-count:{utcStart.Floor(TimeSpan.FromMinutes(15)).Ticks}-{utcEnd.Floor(TimeSpan.FromMinutes(15)).Ticks}");
            var projectIds        = stacks.Select(s => s.ProjectId).Distinct().ToList();
            var cachedTotals      = await scopedCacheClient.GetAllAsync <double>(projectIds);

            var totals = cachedTotals.Where(kvp => kvp.Value.HasValue).ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Value);

            if (totals.Count == projectIds.Count)
            {
                return(totals);
            }

            var projects = cachedTotals.Where(kvp => !kvp.Value.HasValue).Select(kvp => new Project {
                Id = kvp.Key, OrganizationId = stacks.FirstOrDefault(s => s.ProjectId == kvp.Key)?.OrganizationId
            }).ToList();
            var projectTerms = await _eventStats.GetNumbersTermsStatsAsync("project_id", _distinctUsersFields, utcStart, utcEnd, systemFilter, projects.BuildRetentionFilter());

            // Cache all projects that have more than 10 users for 5 minutes.
            await scopedCacheClient.SetAllAsync(projectTerms.Terms.Where(t => t.Numbers[0] >= 10).ToDictionary(t => t.Term, t => t.Numbers[0]), TimeSpan.FromMinutes(5));

            totals.AddRange(projectTerms.Terms.ToDictionary(kvp => kvp.Term, kvp => kvp.Numbers[0]));

            return(totals);
        }
Esempio n. 2
0
    private async Task <Dictionary <string, double> > GetUserCountByProjectIdsAsync(ICollection <Stack> stacks, AppFilter sf, DateTime utcStart, DateTime utcEnd)
    {
        var scopedCacheClient = new ScopedCacheClient(_cache, $"Project:user-count:{utcStart.Floor(TimeSpan.FromMinutes(15)).Ticks}-{utcEnd.Floor(TimeSpan.FromMinutes(15)).Ticks}");
        var projectIds        = stacks.Select(s => s.ProjectId).Distinct().ToList();
        var cachedTotals      = await scopedCacheClient.GetAllAsync <double>(projectIds);

        var totals = cachedTotals.Where(kvp => kvp.Value.HasValue).ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Value);

        if (totals.Count == projectIds.Count)
        {
            return(totals);
        }

        var systemFilter = new RepositoryQuery <PersistentEvent>().AppFilter(sf).DateRange(utcStart, utcEnd, (PersistentEvent e) => e.Date).Index(utcStart, utcEnd);
        var projects     = cachedTotals.Where(kvp => !kvp.Value.HasValue).Select(kvp => new Project {
            Id = kvp.Key, OrganizationId = stacks.FirstOrDefault(s => s.ProjectId == kvp.Key)?.OrganizationId
        }).ToList();
        var countResult = await _eventRepository.CountAsync(q => q.SystemFilter(systemFilter).FilterExpression(projects.BuildFilter()).AggregationsExpression("terms:(project_id cardinality:user)"));

        // Cache all projects that have more than 10 users for 5 minutes.
        var projectTerms = countResult.Aggregations.Terms <string>("terms_project_id").Buckets;
        var aggregations = projectTerms.ToDictionary(t => t.Key, t => t.Aggregations.Cardinality("cardinality_user").Value.GetValueOrDefault());
        await scopedCacheClient.SetAllAsync(aggregations.Where(t => t.Value >= 10).ToDictionary(k => k.Key, v => v.Value), TimeSpan.FromMinutes(5));

        totals.AddRange(aggregations);

        return(totals);
    }