private async Task AutoClearLoopAsync <TKey, TEntity>(IEntityCache <TKey, TEntity> cache, string optionsName, IBatchingStore store, CancellationToken cancellationToken = default) where TEntity : IEntity <TKey> { CachingOptions options = _cachingOptions.Get(optionsName); if (options.Lifetime < TimeSpan.Zero) { _log.LogDebug("{ServiceName} cache lifetime set to 0 or lower, cache purges disabled", cache.GetType().Name); return; } _log.LogDebug("{ServiceName} starting cache auto-clear loop with rate of {ClearRate}", cache.GetType().Name, options.Lifetime); while (!cancellationToken.IsCancellationRequested) { await Task.Delay(options.Lifetime, cancellationToken).ConfigureAwait(false); // flush batch to prevent data loss store?.FlushBatch(); // find and remove entities from cache IEnumerable <TEntity> expired = cache.Find(e => e.IsExpired(options.Lifetime)); foreach (TEntity entity in expired) { cache.Remove(entity.ID); } _log.LogDebug("{RemovedCount} expired {ServiceName} entities removed from cache", expired.Count(), cache.GetType().Name); } }
public static void RemoveWhere <TKey, TEntity>(this IEntityCache <TKey, TEntity> cache, Func <CachedEntity <TKey, TEntity>, bool> predicate) { IEnumerable <CachedEntity <TKey, TEntity> > selectedEntities = cache.Find(predicate); foreach (CachedEntity <TKey, TEntity> entity in selectedEntities) { cache.Remove(entity.Key); } }
public async Task <PatchbotGame> GetAsync(string name, CancellationToken cancellationToken = default) { string trimmedName = name.Trim(); string lowercaseName = trimmedName.ToLowerInvariant(); await _lock.WaitAsync(cancellationToken).ConfigureAwait(false); try { PatchbotGame result; CachingOptions cachingOptions = _cachingOptions.Get(CacheOptionName); if (cachingOptions.Enabled) { result = _patchbotGameCache.Find(e => e.Entity.MatchesName(trimmedName)).FirstOrDefault(); if (result != null) { _log.LogTrace("Patchbot game {Game} found in cache", trimmedName); return(result); } } // get from DB _log.LogTrace("Retrieving patchbot game {Game} from database", trimmedName); FilterDefinition <PatchbotGame> filter = Builders <PatchbotGame> .Filter.Or( Builders <PatchbotGame> .Filter.Regex(dbData => dbData.Name, new BsonRegularExpression($"/^{trimmedName}$/i")), Builders <PatchbotGame> .Filter.AnyEq(dbData => dbData.Aliases, lowercaseName)); result = await _collection.Find(filter).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); // if not found, return null if (result == null) { _log.LogTrace("Patchbot game {Game} not found", trimmedName); return(null); } _patchbotGameCache.AddOrReplace(result.Name, result, cachingOptions.Lifetime); return(result); } finally { _lock.Release(); } }
public async Task <IEnumerable <StellarisMod> > GetAllAsync(CancellationToken cancellationToken = default) { await _lock.WaitAsync(cancellationToken).ConfigureAwait(false); try { CachingOptions cachingOptions = _cachingOptions.Get(CacheOptionName); if (cachingOptions.Enabled && _lastCacheTimeUtc + cachingOptions.Lifetime < DateTime.UtcNow) { _log.LogTrace("Stellaris mods found in cache"); return(_stellarisModsCache.Find(_ => true).Select(e => e.Entity)); } _log.LogDebug("Retrieving Stellaris mods from database"); IEnumerable <StellarisMod> results = await _collection.Find(_ => true).ToListAsync(cancellationToken).ConfigureAwait(false); if (results?.Any() != true) { _log.LogTrace("Stellaris mods not found, returning empty"); results = Enumerable.Empty <StellarisMod>(); } if (cachingOptions.Enabled) { _stellarisModsCache.Clear(); foreach (StellarisMod mod in results) { _stellarisModsCache.AddOrReplace(mod.ID, mod, cachingOptions.Lifetime); } } return(results); } finally { _lock.Release(); } }