[NotNull, ItemNotNull] public async Task <IReadOnlyList <IUrbanDefinition> > SearchTermAsync(string term) { //Sanity check term encodes into URL form var urlTerm = HttpUtility.UrlEncode(term); if (urlTerm == null) { return(Array.Empty <IUrbanDefinition>()); } //Try to get from the cache var item = await _definitionsByWord.GetItem(urlTerm); if (item != null) { return(item.Entries); } //Get it from the API, early exit if we get nothing var response = await SearchTermNoCacheAsync(urlTerm); if (response == null) { return(Array.Empty <IUrbanDefinition>()); } //Add it to the cache _definitionCache.Add(new CacheEntry(urlTerm, response.Entries)); //Return the result return(response.Entries); }
public When_adding_the_same_new_item_concurrently() { Given(() => { cache = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now); indexById = cache.AddIndex("index", user => user.Id); }); When(() => { Parallel.For(1, 1000, _ => { try { cache.Add(new User { Id = "item1", Name = "Item1" }); } catch (InvalidOperationException) { // Expected, so ignore } }); }); }
public When_concurrently_adding_unique_items_directly_or_through_a_get() { Given(() => { cache = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now); indexById = cache.AddIndex("index", user => user.Id, id => Task.FromResult(new User { Id = id })); }); When(() => { Parallel.For(0, 1000, iteration => { if (iteration % 2 == 0) { cache.Add(new User { Id = iteration.ToString(), Name = iteration.ToString() }); } else { indexById.GetItem(iteration.ToString(), key => Task.FromResult(new User { Id = key, Name = key })); } }); }); }
public When_a_case_insensitive_comparer_is_used_for_an_index_and_getting_an_item_by_the_key_with_a_different_case() { Given(() => { cache = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now); indexById = cache.AddIndex("index", user => user.Id, keyEqualityComparer: StringComparer.OrdinalIgnoreCase); UseThe(new User { Id = "TheId" }); cache.Add(The <User>()); }); When(() => indexById.GetItem("theID")); }
private async Task <TItem> GetOrDownload <TKey, TItem, TResponse>(TKey key, FluidCache <TItem> cache, IIndex <TKey, TItem> index, Func <TKey, Task <HttpResponseMessage> > download, Func <TResponse, IEnumerable <TItem> > extract) where TItem : class { //Get it from the cache if possible var item = await index.GetItem(key); if (item != null) { return(item); } //No luck, download the details from the API var result = await download(key); if (!result.IsSuccessStatusCode) { return(null); } //Deserialize response TResponse model; var serializer = new JsonSerializer(); using (var sr = new StreamReader(await result.Content.ReadAsStreamAsync())) using (var jsonTextReader = new JsonTextReader(sr)) model = serializer.Deserialize <TResponse>(jsonTextReader); if (model == null) { return(null); } var extracted = extract(model); if (extracted == null) { return(null); } //That could get several currencies, add them all to cache foreach (var extractedItem in extracted) { cache.Add(extractedItem); } //Get the item from cache again, hopefully with more success this time return(await index.GetItem(key)); }
public When_an_item_did_exist_in_the_cache() { Given(() => { cache = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now); indexById = cache.AddIndex("index", user => user.Id, id => Task.FromResult(new User { Id = id })); cache.Add(new User { Id = "itemkey" }); }); When(async() => { await indexById.GetItem("itemkey"); }); }
private async Task <TItem?> GetItemAsyncCached(AnilistClient client, TSearchItem searchItem) { var cached = await _itemById.GetItem(ExtractId(searchItem)); if (cached != null) { return(cached); } var item = await GetItemAsync(client, searchItem); if (item == null) { return(null); } _cache.Add(item); return(item); }
public void Add(TProjection projection) { cache.Add(projection); }
public void Add(IHaveIdentity projection) { cache.Add(projection); }