static IObservable <T> GetAndFetchLatestFromIndex <T>(this IBlobCache This, string key, Func <IObservable <T> > fetchFunc, Action <T> removedItemsCallback, Func <DateTimeOffset, bool> fetchPredicate = null, DateTimeOffset?absoluteExpiration = null, bool shouldInvalidateOnError = false) where T : CacheItem { var idx = Observable.Defer(() => This .GetOrCreateObject(key, () => CacheIndex.Create(key))) .Select(x => x.IndexKey == null ? CacheIndex.Create(key) : x) .Replay() .RefCount(); var fetch = idx .Select(x => Tuple.Create(x, fetchPredicate == null || !x.Keys.Any() || fetchPredicate(x.UpdatedAt))) .Where(predicateIsTrue => predicateIsTrue.Item2) .Select(x => x.Item1) .Select(index => index.Clear()) .SelectMany(index => fetchFunc() .Catch <T, Exception>(ex => { var shouldInvalidate = shouldInvalidateOnError ? This.InvalidateObject <CacheIndex>(key) : Observable.Return(Unit.Default); return(shouldInvalidate.SelectMany(__ => Observable.Throw <T>(ex))); }) .SelectMany(x => x.Save <T>(This, key, absoluteExpiration)) .Do(x => index.Add(key, x)) ); var cache = idx .SelectMany(index => This.GetObjects <T>(index.Keys.ToList())) .SelectMany(dict => dict.Values); return(cache.Merge(fetch) .Finally(async() => { var index = await idx; await index.Save(This); var list = index.OldKeys.Except(index.Keys); if (!list.Any()) { return; } var removed = await This.GetObjects <T>(list); foreach (var d in removed.Values) { removedItemsCallback(d); } await This.InvalidateObjects <T>(list); }) .Replay().RefCount()); }
static IObservable <T> GetAndFetchLatestFromIndex <T>(this IBlobCache This, string key, Func <IObservable <T> > fetchFunc, Action <T> removedItemsCallback, Func <DateTimeOffset, bool> fetchPredicate = null, DateTimeOffset?absoluteExpiration = null, bool shouldInvalidateOnError = false) where T : CacheItem { var fetch = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key)) .Select(x => Tuple.Create(x, fetchPredicate == null || !x.Keys.Any() || fetchPredicate(x.UpdatedAt))) .Where(predicateIsTrue => predicateIsTrue.Item2) .Select(x => x.Item1) .SelectMany(index => index.Clear(This, key, absoluteExpiration)) .SelectMany(index => { var fetchObs = fetchFunc().Catch <T, Exception>(ex => { var shouldInvalidate = shouldInvalidateOnError ? This.InvalidateObject <CacheIndex>(key) : Observable.Return(Unit.Default); return(shouldInvalidate.SelectMany(__ => Observable.Throw <T>(ex))); }); return(fetchObs .SelectMany(x => x.Save <T>(This, key, absoluteExpiration)) .Do(x => index.AddAndSave(This, key, x, absoluteExpiration)) .Finally(() => { This.GetObjects <T>(index.OldKeys.Except(index.Keys)) .Do(dict => This.InvalidateObjects <T>(dict.Keys)) .SelectMany(dict => dict.Values) .Do(removedItemsCallback) .Subscribe(); })); })); var cache = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key)) .SelectMany(index => This.GetObjects <T>(index.Keys)) .SelectMany(dict => dict.Values)); return(cache.Merge(fetch).Replay().RefCount()); }
/// <summary> /// Get all objects by the provided keys. /// Returns null if no object is found. /// </summary> /// <param name="keys">Keys to look-up</param> /// <returns>Key-Value pair Dictionary</returns> public virtual async Task<IDictionary<string, T>> Get<T>(IEnumerable<string> keys) where T : class, IKeyProvider { try { return await _blobCache.GetObjects<T>(keys); } catch (KeyNotFoundException) { return null; } }
public async Task <IDictionary <string, T> > GetKeyPairsFromCache <T>(IEnumerable <string> keys) { try { IDictionary <string, T> t = await Cache.GetObjects <T>(keys); return(t); } catch (KeyNotFoundException) { return(default(IDictionary <string, T>)); } }