Пример #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);
        }
Пример #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);
    }
Пример #3
0
        public virtual async Task CanUseScopedCaches()
        {
            var cache = GetCacheClient();

            if (cache == null)
            {
                return;
            }

            using (cache) {
                await cache.RemoveAllAsync();

                var scopedCache1       = new ScopedCacheClient(cache, "scoped1");
                var nestedScopedCache1 = new ScopedCacheClient(scopedCache1, "nested");
                var scopedCache2       = new ScopedCacheClient(cache, "scoped2");

                await cache.SetAsync("test", 1);

                await scopedCache1.SetAsync("test", 2);

                await nestedScopedCache1.SetAsync("test", 3);

                Assert.Equal(1, (await cache.GetAsync <int>("test")).Value);
                Assert.Equal(2, (await scopedCache1.GetAsync <int>("test")).Value);
                Assert.Equal(3, (await nestedScopedCache1.GetAsync <int>("test")).Value);

                Assert.Equal(3, (await scopedCache1.GetAsync <int>("nested:test")).Value);
                Assert.Equal(3, (await cache.GetAsync <int>("scoped1:nested:test")).Value);

                // ensure GetAllAsync returns unscoped keys
                Assert.Equal("test", (await scopedCache1.GetAllAsync <int>("test")).Keys.FirstOrDefault());
                Assert.Equal("test", (await nestedScopedCache1.GetAllAsync <int>("test")).Keys.FirstOrDefault());

                await scopedCache2.SetAsync("test", 1);

                var result = await scopedCache1.RemoveByPrefixAsync(String.Empty);

                Assert.Equal(2, result);

                // delete without any matching keys
                result = await scopedCache1.RemoveByPrefixAsync(String.Empty);

                Assert.Equal(0, result);

                Assert.False((await scopedCache1.GetAsync <int>("test")).HasValue);
                Assert.False((await nestedScopedCache1.GetAsync <int>("test")).HasValue);
                Assert.Equal(1, (await cache.GetAsync <int>("test")).Value);
                Assert.Equal(1, (await scopedCache2.GetAsync <int>("test")).Value);

                await scopedCache2.RemoveAllAsync();

                Assert.False((await scopedCache1.GetAsync <int>("test")).HasValue);
                Assert.False((await nestedScopedCache1.GetAsync <int>("test")).HasValue);
                Assert.False((await scopedCache2.GetAsync <int>("test")).HasValue);
                Assert.Equal(1, (await cache.GetAsync <int>("test")).Value);
            }
        }