Esempio n. 1
0
        public void SelectorsRoundtrip()
        {
            var selectors          = Enumerable.Range(0, 3).Select(_ => Selector.Random()).ToList();
            var redisValues        = _serializer.ToRedisValues(selectors);
            var roundtrippedValues = _serializer.AsSelectors(redisValues);

            Assert.Equal(selectors, roundtrippedValues);
        }
Esempio n. 2
0
        private async Task <Result <Selector[]> > GetOrAddSelectorsAsync(
            Context context,
            Fingerprint weakFingerprint,
            Func <Fingerprint, Task <Result <Selector[]> > > getFunc,
            CancellationToken cancellationToken)
        {
            try
            {
                var cacheKey = _redisSerializer.ToRedisKey(weakFingerprint);

                RedisValue[] cacheSelectors;

                Stopwatch stopwatch = Stopwatch.StartNew();
                try
                {
                    _cacheTracer.GetDistributedSelectorsStart(context);
                    cacheSelectors = await GetSetMembersWithExpiryBumpAsync(context, cacheKey);
                }
                finally
                {
                    _cacheTracer.GetDistributedSelectorsStop(context, stopwatch.Elapsed);
                }

                if (cacheSelectors.Length == 0)
                {
                    _cacheTracer.RecordSelectorsFetchedFromBackingStore(context, weakFingerprint);
                    Result <Selector[]> selectorResults = await getFunc(weakFingerprint).ConfigureAwait(false);

                    if (!selectorResults || selectorResults.Value.Length == 0)
                    {
                        // Redis throws an error if set add is called without any values. Also, undefined keys are treated as empty sets.
                        // So currently skip trying to cache GetSelectors returning empty.
                        // If needed, we need to create a sentinel value to denote an known empty set v/s undefined.
                        return(selectorResults);
                    }

                    {
                        var selectors   = selectorResults.Value;
                        var cacheValues = _redisSerializer.ToRedisValues(selectors);

                        stopwatch = Stopwatch.StartNew();
                        try
                        {
                            _cacheTracer.AddSelectorsStart(context);
                            var addedCount = await AddSetMembersWithExpiryBumpAsync(context, cacheKey, cacheValues);

                            if (cacheValues.Length != addedCount)
                            {
                                _tracer.Warning(context, $"Expected to add {cacheValues.Length} members but actually added {addedCount}.");
                            }

                            _tracer.Debug(context, $"Added redis cache entry for {weakFingerprint}: {selectors.Length} selectors.");
                        }
                        finally
                        {
                            _cacheTracer.AddSelectorsStop(context, stopwatch.Elapsed);
                        }
                    }

                    return(selectorResults);
                }
                else
                {
                    Selector[] result = _redisSerializer.AsSelectors(cacheSelectors).ToArray();
                    _cacheTracer.RecordSelectorsFetchedDistributed(context, weakFingerprint, result.Length);
                    return(result);
                }
            }
            catch (Exception ex)
            {
                return(Result.FromException <Selector[]>(ex));
            }
        }