Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
billhong-just committed Sep 11, 2023
1 parent 0402013 commit 280a96d
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 70 deletions.
61 changes: 60 additions & 1 deletion src/EasyCaching.Core/EasyCachingAbstractProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,55 @@ public async Task FlushAsync(CancellationToken cancellationToken = default)
}
}

public CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, Func<TimeSpan> expirationRetriever)
{
var operationId = s_diagnosticListener.WriteGetCacheBefore(new BeforeGetRequestEventData(CachingProviderType.ToString(), Name, nameof(Get), new[] { cacheKey }, expiration));

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context

Check failure on line 189 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context
Exception e = null;
try
{
if (_lockFactory == null) return BaseGet<T>(cacheKey, dataRetriever, expirationRetriever);

Check failure on line 193 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

Argument 3: cannot convert from 'System.Func<System.TimeSpan>' to 'System.TimeSpan'

Check failure on line 193 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

Argument 3: cannot convert from 'System.Func<System.TimeSpan>' to 'System.TimeSpan'

Check failure on line 193 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

Argument 3: cannot convert from 'System.Func<System.TimeSpan>' to 'System.TimeSpan'

Check failure on line 193 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

Argument 3: cannot convert from 'System.Func<System.TimeSpan>' to 'System.TimeSpan'

Check failure on line 193 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

Argument 3: cannot convert from 'System.Func<System.TimeSpan>' to 'System.TimeSpan'

Check failure on line 193 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

Argument 3: cannot convert from 'System.Func<System.TimeSpan>' to 'System.TimeSpan'

var value = BaseGet<T>(cacheKey);
if (value.HasValue) return value;

using (var @lock = _lockFactory.CreateLock(Name, $"{cacheKey}_Lock"))
{
if (!@lock.Lock(_options.SleepMs)) throw new TimeoutException();

value = BaseGet<T>(cacheKey);
if (value.HasValue) return value;

var item = dataRetriever();
if (item != null || _options.CacheNulls)
{
BaseSet(cacheKey, item, expiration);

Check failure on line 208 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 208 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 208 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

The name 'expiration' does not exist in the current context

Check failure on line 208 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context

Check failure on line 208 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context

Check failure on line 208 in src/EasyCaching.Core/EasyCachingAbstractProvider.cs

View workflow job for this annotation

GitHub Actions / build and test on ubuntu-latest

The name 'expiration' does not exist in the current context

return new CacheValue<T>(item, true);
}
else
{
return CacheValue<T>.NoValue;
}
}
}
catch (Exception ex)
{
e = ex;
throw;
}
finally
{
if (e != null)
{
s_diagnosticListener.WriteGetCacheError(operationId, e);
}
else
{
s_diagnosticListener.WriteGetCacheAfter(operationId);
}
}
}

public CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, TimeSpan expiration)
{
var operationId = s_diagnosticListener.WriteGetCacheBefore(new BeforeGetRequestEventData(CachingProviderType.ToString(), Name, nameof(Get), new[] { cacheKey }, expiration));
Expand Down Expand Up @@ -363,6 +412,16 @@ public async Task<IDictionary<string, CacheValue<T>>> GetAllAsync<T>(IEnumerable
}
}

public Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, Func<Task<TimeSpan>> expirationRetriever, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}

public Task<object> GetAsync(string cacheKey, Type type, Func<Task<object>> dataRetriever, Func<Task<TimeSpan>> expirationRetriever, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}

public async Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, TimeSpan expiration, CancellationToken cancellationToken = default)
{
var operationId = s_diagnosticListener.WriteGetCacheBefore(new BeforeGetRequestEventData(CachingProviderType.ToString(), Name, nameof(GetAsync), new[] { cacheKey }, expiration));
Expand Down Expand Up @@ -947,6 +1006,6 @@ protected SearchKeyPattern ProcessSearchKeyPattern(string pattern)
protected string HandleSearchKeyPattern(string pattern)
{
return pattern.Replace("*", string.Empty);
}
}
}
}
32 changes: 32 additions & 0 deletions src/EasyCaching.Core/IEasyCachingProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ public interface IEasyCachingProviderBase
/// <typeparam name="T">The 1st type parameter.</typeparam>
CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, TimeSpan expiration);

/// <summary>
/// Get the specified cacheKey, dataRetriever and expirationRetriever.
/// </summary>
/// <returns>The get.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expirationRetriever">Expiration retriever.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, Func<TimeSpan> expirationRetriever);

/// <summary>
/// Gets the specified cacheKey, dataRetriever and expiration async.
/// </summary>
Expand All @@ -153,6 +163,28 @@ public interface IEasyCachingProviderBase
/// <typeparam name="T">The 1st type parameter.</typeparam>
Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, TimeSpan expiration, CancellationToken cancellationToken = default);

/// <summary>
/// Gets the specified cacheKey, dataRetriever and expirationRetriever async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expirationRetriever">Expiration retriever.</param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, Func<Task<TimeSpan>> expirationRetriever, CancellationToken cancellationToken = default);

/// <summary>
/// Gets the specified cacheKey, type, dataRetriever and expirationRetriever async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="type">Object Type.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expirationRetriever">Expiration retriever.</param>
/// <param name="cancellationToken"></param>
Task<object> GetAsync(string cacheKey, Type type, Func<Task<object>> dataRetriever, Func<Task<TimeSpan>> expirationRetriever, CancellationToken cancellationToken = default);

/// <summary>
/// Removes cached item by cachekey's prefix.
/// </summary>
Expand Down
197 changes: 128 additions & 69 deletions src/EasyCaching.HybridCache/HybridCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ public CacheValue<T> Get<T>(string cacheKey)
// 但這有 async 問題,async 下,直接傳入 expiration 是 sync,但需要延後取得 expiration 是 async。
// 不過確實可以用 Task.FromResult(expiration); 來強制變成 async 界面
// https://github.com/dotnetcore/EasyCaching/pull/480/files#diff-d8769ba5cc06870491bb7918cb090bcfc19e1f9b56b545e8c023063bbf67c259L166
TimeSpan ts = GetExpiration(cacheKey);
var result = _localCache.Get(
cacheKey,
() =>
Expand All @@ -278,7 +277,8 @@ public CacheValue<T> Get<T>(string cacheKey)
throw;
}
return value;
}, ts);
},
() => GetExpiration(cacheKey));
return result;
}

Expand All @@ -292,42 +292,26 @@ public CacheValue<T> Get<T>(string cacheKey)
public async Task<CacheValue<T>> GetAsync<T>(string cacheKey, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

var cacheValue = await _localCache.GetAsync<T>(cacheKey, cancellationToken);

if (cacheValue.HasValue)
{
return cacheValue;
}

LogMessage($"local cache can not get the value of {cacheKey}");

try
{
cacheValue = await _distributedCache.GetAsync<T>(cacheKey, cancellationToken);
}
catch (Exception ex)
{
LogMessage($"distributed cache get error, [{cacheKey}]", ex);

if (_options.ThrowIfDistributedCacheError)
var result = await _localCache.GetAsync(
cacheKey,
async () =>
{
throw;
}
}

if (cacheValue.HasValue)
{
TimeSpan ts = await GetExpirationAsync(cacheKey, cancellationToken);

await _localCache.SetAsync(cacheKey, cacheValue.Value, ts, cancellationToken);

return cacheValue;
}

LogMessage($"distributed cache can not get the value of {cacheKey}");

return CacheValue<T>.NoValue;
var value = default(T);
try
{
value = (await _distributedCache.GetAsync<T>(cacheKey, cancellationToken)).Value;
}
catch (Exception ex)
{
LogMessage($"distributed cache get error, [{cacheKey}]", ex);
if (_options.ThrowIfDistributedCacheError)
throw;
}
return value;
},
() => GetExpirationAsync(cacheKey, cancellationToken),
cancellationToken);
return result;
}

/// <summary>
Expand Down Expand Up @@ -687,15 +671,28 @@ public CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, TimeSpan exp
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
TimeSpan ts = GetExpiration(cacheKey);
return Get(cacheKey, dataRetriever, () => expiration);
}

/// <summary>
/// Get the specified cacheKey, dataRetriever and expirationRetriever.
/// </summary>
/// <returns>The get.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expirationRetriever">Expiration retriever.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, Func<TimeSpan> expirationRetriever)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
var result = _localCache.Get(
cacheKey,
() =>
{
var value = default(T);
try
{
value = _distributedCache.Get(cacheKey, dataRetriever, expiration).Value;
value = _distributedCache.Get(cacheKey, dataRetriever, expirationRetriever).Value;
}
catch (Exception ex)
{
Expand All @@ -704,7 +701,8 @@ public CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, TimeSpan exp
throw;
}
return value;
}, ts);
},
() => GetExpiration(cacheKey));
return result;
}

Expand All @@ -721,38 +719,76 @@ public async Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> data
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
return await GetAsync(cacheKey, dataRetriever, () => Task.FromResult(expiration), cancellationToken);
}

var result = await _localCache.GetAsync<T>(cacheKey, cancellationToken);

if (result.HasValue)
{
return result;
}

try
{
result = await _distributedCache.GetAsync<T>(cacheKey, dataRetriever, expiration, cancellationToken);
}
catch (Exception ex)
{
LogMessage($"get async with data retriever from distributed provider error [{cacheKey}]", ex);

if (_options.ThrowIfDistributedCacheError)
/// <summary>
/// Gets the specified cacheKey, dataRetriever and expirationRetriever async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expirationRetriever">Expiration retriever.</param>
/// <param name="cancellationToken"></param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, Func<Task<TimeSpan>> expirationRetriever, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
var result = await _localCache.GetAsync(
cacheKey,
async () =>
{
throw;
}
}

if (result.HasValue)
{
TimeSpan ts = await GetExpirationAsync(cacheKey, cancellationToken);

await _localCache.SetAsync(cacheKey, result.Value, ts, cancellationToken);

return result;
}
var value = default(T);
try
{
value = (await _distributedCache.GetAsync(cacheKey, dataRetriever, expirationRetriever, cancellationToken)).Value;
}
catch (Exception ex)
{
LogMessage($"get async with data retriever from distributed provider error [{cacheKey}]", ex);
if (_options.ThrowIfDistributedCacheError)
throw;
}
return value;
},
() => GetExpirationAsync(cacheKey, cancellationToken),
cancellationToken);
return result;
}

return CacheValue<T>.NoValue;
/// <summary>
/// Gets the specified cacheKey, type, dataRetriever and expirationRetriever async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="type">Object Type.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expirationRetriever">Expiration retriever.</param>
/// <param name="cancellationToken"></param>
public async Task<object> GetAsync(string cacheKey, Type type, Func<Task<object>> dataRetriever, Func<Task<TimeSpan>> expirationRetriever, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
var result = await _localCache.GetAsync(
cacheKey,
type,
async () =>
{
object value = null;
try
{
value = await _distributedCache.GetAsync(cacheKey, type, dataRetriever, expirationRetriever, cancellationToken);
}
catch (Exception ex)
{
LogMessage($"get async with data retriever from distributed provider error [{cacheKey}]", ex);
if (_options.ThrowIfDistributedCacheError)
throw;
}
return value;
},
() => GetExpirationAsync(cacheKey, cancellationToken),
cancellationToken);
return result;
}

/// <summary>
Expand Down Expand Up @@ -936,6 +972,29 @@ private TimeSpan GetExpiration(string cacheKey)

public async Task<object> GetAsync(string cacheKey, Type type, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
var result = await _localCache.GetAsync(
cacheKey,
type,
async () =>
{
object value = null;
try
{
value = await _distributedCache.GetAsync(cacheKey, type, cancellationToken);
}
catch (Exception ex)
{
LogMessage($"distributed cache get error, [{cacheKey}]", ex);
if (_options.ThrowIfDistributedCacheError)
throw;
}
return value;
},
() => GetExpirationAsync(cacheKey, cancellationToken),
cancellationToken);
return result;

ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

var cacheValue = await _localCache.GetAsync(cacheKey, type, cancellationToken);
Expand Down

0 comments on commit 280a96d

Please sign in to comment.