private void AssertTopicRule(CacheRule rule, string absName) { int count = CountTopicRuleMatches(rule, absName); if (count == 0) System.Console.Error.WriteLine("Rule: " + rule.Description); Assert.IsTrue(count > 0, "Searching for topic (" + absName + ") in cache rule"); }
public void when_deleted_then_execute_cached_then_get_then_check_result() { var result = cacheProvider.ExecuteCached(new CacheKey(GetType().FullName + "::ComplexReference::Check"), () => new ComplexObj(), CacheRule.Delete()); result = cacheProvider.Get <ComplexObj>(new CacheKey(GetType().FullName + "::ComplexReference::Check")); Assert.IsNull(result); result = cacheProvider.ExecuteCached(new CacheKey(GetType().FullName + "::ComplexReference::Check"), () => new ComplexObj(), TimeSpan.FromSeconds(4)); Assert.AreEqual(new ComplexObj().A, result.A); Assert.AreEqual(new ComplexObj().B, result.B); Thread.Sleep(4000); result = cacheProvider.Get <ComplexObj>(new CacheKey(GetType().FullName + "::ComplexReference::Check")); Assert.IsNull(result); }
private T ExecuteCachedInside <T>(CacheKey cacheKey, Func <T> cachedItem, CacheRule cacheRule) { var cachingProviderTokenSource = new CancellationTokenSource(cancellationTimeoutMs); var cacheValue = Get <T>(cacheKey); if (cacheRule.ToDelete) { var svcCount = services.Count; var serviceTasks = new Task[svcCount]; for (int i = 0; i < svcCount; i++) { var i1 = i; var task = Task.Factory.StartNew(() => { var svcId = services.ElementAt(i1).Key; var svc = services[svcId]; svc.Delete(cacheKey); }, cachingProviderTokenSource.Token); serviceTasks[i1] = task; } Task.WaitAll(serviceTasks, cachingProviderTokenSource.Token); return(default(T)); } if (EqualityComparer <T> .Default.Equals(cacheValue, default(T)) || cacheRule.BypassCache) { var result = cachedItem(); var svcCount = services.Count; var serviceTasks = new Task[svcCount]; for (int i = 0; i < svcCount; i++) { var i1 = i; var task = Task.Factory.StartNew(() => { var svcId = services.ElementAt(i1).Key; var svc = services[svcId]; svc.Set(cacheKey, new CacheValue(serializer.Serialize(result)), cacheRule); }, cachingProviderTokenSource.Token); serviceTasks[i1] = task; } Task.WaitAll(serviceTasks, cachingProviderTokenSource.Token); return(result); } return(cacheValue); }
private int CountTopicRuleMatches(CacheRule rule, string path) { int found = 0; foreach (CacheRule r in rule.AllLeafRules) { if (r is TopicsCacheRule) { TopicsCacheRule tcr = (TopicsCacheRule)r; foreach (AbsoluteTopicName p in tcr.Topics) { if (p.ToString().IndexOf(path) >= 0) { found++; } } } } return found; }
public void Add(CacheRule aRule) { _Children.Add(aRule); }
public void Put(string key, object val, CacheRule rule) { cache[key] = val; rules[key] = rule; }
public void Set(CacheKey cacheKey, CacheValue cacheObj, CacheRule cacheRule) { var db = CacheEndpoint.GetDatabase(); db.StringSet(cacheKey.ToString(), cacheObj.Value, cacheRule.ExpiresIn); }
public void execute_cached_for_delete_only() { cacheProvider.ExecuteCached(new CacheKey(GetType().FullName + "::PrimitiveReference::DeleteOnly"), () => Guid.NewGuid(), CacheRule.Delete()); Assert.True(true); var result = cacheProvider.Get <Guid>(new CacheKey(GetType().FullName + "::PrimitiveReference::DeleteOnly")); Assert.AreEqual(Guid.Empty.ToString(), result.ToString()); }
public Task <T> ExecuteCachedAsync <T>(CacheKey cacheKey, Func <T> cacheFunc, CacheRule cacheRule) { return(Task.Factory.StartNew(() => ExecuteCached(cacheKey, cacheFunc, cacheRule))); }
public void PutCachedTopicsWithProperty(string propertyName, TopicInfoArray val, CacheRule rule) { string key = KeyForProperty(propertyName); Put(key, val, rule); rule.SetupInvalidation(this, key); }
public void PutCachedTopic(AbsoluteTopicName name, CachedTopic val, CacheRule rule) { string key = KeyForTopicInfo(name); Put(key, val, rule); rule.SetupInvalidation(this, key); }
void Put(string key, object val, CacheRule rule) { Cache.Put(key, val, rule); }
/// <summary> /// Gets the asset from the server. /// </summary> /// <returns>The asset.</returns> /// <param name="assetId">Asset identifier.</param> /// <param name="handler">Callback delegate to hand the asset to.</param> /// <param name="cacheRule">Bitfield controlling how local storage is to be handled when used as a cache for remote servers.</param> public void GetAssetAsync(Guid assetId, AssetHandler handler, CacheRule cacheRule) { // Ask for null, get null. if (assetId == Guid.Empty) { handler(null); } // TODO: see if https://github.com/Reactive-Extensions/Rx.NET would do a better job, but they have to finish releasing 4.0 first. // It might be beneficial to move the listener processsing to another thread, but then you potentially lose parallism across multiple asset IDs. StratusAsset result = null; while (true) { // Hit up the local storage first. If there's no upstream then ignore skipread. if (!(cacheRule.HasFlag(CacheRule.SkipRead) && _config.SerialParallelAssetServers.Any()) && (_localStorage?.TryGetAsset(assetId, out result) ?? false)) { handler(result); return; } var listeners = new Queue <AssetHandler>(); listeners.Enqueue(handler); // Add myself to the new listeners list first thing, assuming, probably wrongly, that the following test is true. If wrong, meh: this queue gets dropped like an old potato. if (_idsBeingFetched.TryAdd(assetId, listeners)) { // Got to go try the servers now. foreach (var parallelServers in _config.SerialParallelAssetServers) { if (parallelServers.Count() == 1) // Optimization: no need to hit up the parallel stuff if there's only 1. { result = parallelServers.First().RequestAssetSync(assetId); } else { result = parallelServers.AsParallel().Select(server => server.RequestAssetSync(assetId)).FirstOrDefault(a => a != null); } if (result != null) { if (!cacheRule.HasFlag(CacheRule.SkipWrite)) { _localStorage?.StoreAsset(result); } break; } } // Now to process the listeners. var exceptions = new ConcurrentQueue <Exception>(); lock (listeners) { // Prevent new listeners from being added. Parallel.ForEach(listeners, waiting_handler => { if (waiting_handler == null) { LOG.Log(Logging.LogLevel.Warn, () => $"Attempted to process a handler for assetId {assetId} that was null!"); return; } try { waiting_handler(result); } catch (Exception e) { exceptions.Enqueue(e); } }); _idsBeingFetched.TryRemove(assetId, out var trash); } if (exceptions.Count > 0) { LOG.Log(Logging.LogLevel.Error, () => $"Exceptions ({exceptions.Count}) were thrown by handler(s) listening for asset {assetId}", new AggregateException(exceptions)); } return; // We're done here. } // See if we can add ourselves to the listener list. if (_idsBeingFetched.TryGetValue(assetId, out listeners)) { // Skiplock: if the lock cannot be taken, move on to the retry because the list is already being emptied. var lockTaken = false; try { Monitor.TryEnter(listeners, ref lockTaken); if (lockTaken) { listeners.Enqueue(handler); return; } } finally { if (lockTaken) { Monitor.Exit(listeners); } } // lock was skipped, therefore that list is already being cleaned out. } // It's gone already, so let's try again as the asset should be in local storage or we should query the servers again. Thread.Sleep(50); } }
public void Put(string key, object val, CacheRule rule) { if (rule.IncludesNeverCacheRule) return; TheCache.Insert(key, val); Tracker[key] = rule; }
public void execute_cached_for_delete_only() { cacheProvider.ExecuteCached(new CacheKey(GetType().FullName + "::PrimitiveReference"), () => "", CacheRule.Delete()); Assert.True(true); }
public void AddCacheRule(CacheRule rule) { _CacheRules.Add(rule); }
public T ExecuteCached <T>(CacheKey cacheKey, Func <T> cacheFunc, CacheRule cacheRule) { return(ExecuteCachedInside(cacheKey, cacheFunc, cacheRule)); }
public void PutCachedTopicFormattedBorder(AbsoluteTopicName name, Border border, string val, CacheRule rule) { string key = KeyForTopicFormattedBorder(name, border); Put(key, val, rule); rule.SetupInvalidation(this, key); }
public void PutCachedNamespaceHistory(string ns, IList history, CacheRule rule) { string key = KeyForNamespaceHistory(ns); Put(key, history, rule); rule.SetupInvalidation(this, key); }
public void PutCachedTopicFormattedContent(AbsoluteTopicName name, bool includeDiffs, string val, CacheRule rule) { string key = KeyForTopicFormattedContent(name, includeDiffs); Put(key, val, rule); rule.SetupInvalidation(this, key); }
/// <summary> /// Add a cache rule to the cache rule accumulator (or ignore if we aren't accumulating) /// </summary> /// <param name="aRule"></param> void AddCacheRule(CacheRule aRule) { if (CacheRuleAccumulator != null) CacheRuleAccumulator.Add(aRule); }
public void PutCachedTopicFormattedContent(AbsoluteTopicName name, AbsoluteTopicName withDiffsToThisTopic, string val, CacheRule rule) { string key = KeyForTopicFormattedContent(name, withDiffsToThisTopic); Put(key, val, rule); rule.SetupInvalidation(this, key); }