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