public Tuple <IList <TElement>, bool> EnrollCollection <TElement>( IBaseCacheKey key, Func <FreshnessRequest, IList <TElement> > filler, params Func <IBaseCacheKey, TElement, IBaseCacheKey>[] keyProjections) where TElement : class { var parameters = BuildParameters(key, (freshness) => { var curriedKey = new RefillerKeyAdapter(key); var curriedFiller = filler; var curriedProjections = keyProjections; return(Refiller(freshness, curriedKey, curriedFiller, curriedProjections)); }); var memo = MemoizeCollection <TElement>(parameters); if (memo != null && memo.Item2) { return(memo); } if (memo == null || memo.Item1 == null) { // something went wrong doing a memoization of the results, so lets just ask the // filler to synthesize and return directly memo = Tuple.Create(filler(FreshnessRequest.Normal), false); } return(memo); }
public void Clear(IBaseCacheKey key) { // null key mean NOTHING to clear if (key == null) { return; } var staleKeysInCache = new List <string>(); var keyAsString = key.Key; var keyAsBaseString = keyAsString + key.PolicyRepository.KeySeparator; var enumerator = HttpRuntime.Cache.GetEnumerator(); while (enumerator.MoveNext()) { string keyInCache = enumerator.Key.ToString(); if (keyInCache == keyAsString || keyInCache.StartsWith(keyAsBaseString)) { staleKeysInCache.Add(keyInCache); } } staleKeysInCache.ForEach(staleKeyInCache => { HttpRuntime.Cache.Remove(staleKeyInCache); Log("Clear", () => "Removed stale key from cache: " + staleKeyInCache); }); }
public static TRet EnrollRetry <TRet>( this ICache cache, IBaseCacheKey cacheKey, Func <FreshnessRequest, TRet> filler) where TRet : class { // if you can't give me a key, I can't save it for you! if (cacheKey == null) { return(default(TRet)); } do { var result = cache.EnrollSingle <TRet>(cacheKey, filler); if (false == result.Item2) { return(result.Item1); } // we we're running, snooze for a second then check the cache.. cache.Snooze(100); var value = cache.Get <TRet>(cacheKey.Key); if (value != null) { return(value); } }while (true); }
internal virtual CacheAddParameters <T> BuildParameters <T>(IBaseCacheKey key, Func <FreshnessRequest, T> filler) where T : class { return(BuildParameters <T>( key.Key , key.Policy , filler)); }
public Tuple <TElement, bool> EnrollSingle <TElement>( IBaseCacheKey key, Func <FreshnessRequest, TElement> filler) where TElement : class { var element = filler(FreshnessRequest.Normal); return(Tuple.Create(element, false)); }
public Tuple <TElement, bool> EnrollSingle <TElement>( IBaseCacheKey key, Func <FreshnessRequest, TElement> filler) where TElement : class { var parameters = BuildParameters(key, filler); return(MemoizeElement(parameters)); }
public Tuple <IList <TElement>, bool> EnrollCollection <TElement>( IBaseCacheKey key, Func <FreshnessRequest, IList <TElement> > filler, params Func <IBaseCacheKey, TElement, IBaseCacheKey>[] keyProjections) where TElement : class { var list = filler(FreshnessRequest.Normal); var keys = MemoizeCollection(key, list, keyProjections); return(Tuple.Create(list, false)); }
private IList <TElement> MemoizeCollection <TElement>( IBaseCacheKey key, IList <TElement> list, params Func <IBaseCacheKey, TElement, IBaseCacheKey>[] keyProjections) { if (list != null) { var keys = new List <IBaseCacheKey>(list.Count); foreach (var element in list) { foreach (var projection in keyProjections) { var elementKey = projection(key, element); keys.Add(elementKey); } } } return(list); }
public RefillerKeyAdapter(IBaseCacheKey wrappedKey) { WrappedKey = wrappedKey; }
public void Clear(IBaseCacheKey key) { }
private IList <IBaseCacheKey> Refiller <TElement>( FreshnessRequest freshness, IBaseCacheKey collectionKey, Func <FreshnessRequest, IList <TElement> > filler, Func <IBaseCacheKey, TElement, IBaseCacheKey>[] keyProjections) where TElement : class { IList <IBaseCacheKey> keys = null; var parameters = BuildParameters(collectionKey, filler); var result = parameters.Fill(freshness); if (result.Item2 || result.Item1 == null) { return(keys); } var list = result.Item1; // clear ALL cache if null return from backing store used to be here... // do NOT store in cache yet, this is not the correct answer-set type yet. var elementPolicies = new ICachePolicy[keyProjections.Length]; keys = new List <IBaseCacheKey>(list.Count); foreach (var element in list) { var collectionPolicy = collectionKey.Policy; int whichProjection = 0; foreach (var projection in keyProjections) { var elementKey = projection(collectionKey, element); if (elementKey == null) // ignore null key projections { continue; } var elementPolicy = elementPolicies[whichProjection]; if (elementPolicy == null) { elementPolicy = elementKey.Policy.Clone(); elementPolicy.RefillCount = 0; // we never refill from underneath if (elementPolicy.AbsoluteSeconds > 0) { if (elementPolicy.AbsoluteSeconds <= collectionPolicy.AbsoluteSeconds) { elementPolicy.AbsoluteSeconds = collectionPolicy.AbsoluteSeconds + 10; // to help serialized expiriation! } } else if (elementPolicy.SlidingSeconds > 0) { if (elementPolicy.SlidingSeconds <= collectionPolicy.SlidingSeconds) { elementPolicy.SlidingSeconds = collectionPolicy.SlidingSeconds + 10; // to help serialized expiriation! } } elementPolicies[whichProjection] = elementPolicy; } // TODO still not right, Marc InternalPut(BuildParameters( elementKey.Key , elementPolicy , ICacheHelper.Once(element)) , element); if (whichProjection++ == 0) { keys.Add(elementKey); } } } return(keys); }