public override IAsyncEnumerable <TResult> ExecuteAsync <TResult>(Expression query) { var asCachingExpressionVisitor = new AsCachingExpressionVisitor(); query = asCachingExpressionVisitor.GetExtractAsCachingParameter(query, out bool asCaching, out CachingOptions options); if (!asCaching) { return(base.ExecuteAsync <TResult>(query)); } var cacheKey = GetCacheKey(query); Task <List <TResult> > valuesTask; if (options.DistributedLock) { valuesTask = _cacheProvider.FetchObjectWithLockAsync(cacheKey, () => base.ExecuteAsync <TResult>(query).ToList(), options.Expiry); } else { valuesTask = _cacheProvider.FetchObjectAsync(cacheKey, () => base.ExecuteAsync <TResult>(query).ToList(), options.Expiry); } //Tricky implementation with custom implementation of AsyncEnumerable with by pass async function inside async iterator, and make code path async all the way down //If execute in current block, we can't await here, and any wait method will blocks thread. return(new MyAsyncEnumerable <TResult>(valuesTask)); }
public override TResult Execute <TResult>(Expression query) { var asCachingExpressionVisitor = new AsCachingExpressionVisitor(); query = asCachingExpressionVisitor.GetExtractAsCachingParameter(query, out bool asCaching, out CachingOptions options); if (!asCaching) { return(base.Execute <TResult>(query)); } var cacheKey = GetCacheKey(query); if (options.DistributedLock) { return(_cacheProvider.FetchObjectWithLock(cacheKey, () => base.Execute <TResult>(query), options.Expiry)); } return(_cacheProvider.FetchObject(cacheKey, () => base.Execute <TResult>(query), options.Expiry)); }
public override async Task <TResult> ExecuteAsync <TResult>(Expression query, CancellationToken cancellationToken) { var asCachingExpressionVisitor = new AsCachingExpressionVisitor(); query = asCachingExpressionVisitor.GetExtractAsCachingParameter(query, out bool asCaching, out CachingOptions options); if (!asCaching) { return(await base.ExecuteAsync <TResult>(query, cancellationToken)); } var cacheKey = GetCacheKey(query); if (options.DistributedLock) { return(await _cacheProvider.FetchObjectWithLockAsync(cacheKey, () => base.ExecuteAsync <TResult>(query, cancellationToken), options.Expiry)); } return(await _cacheProvider.FetchObjectAsync(cacheKey, () => base.ExecuteAsync <TResult>(query, cancellationToken), options.Expiry)); }