Skip to content

Commit

Permalink
Clear lock on exception in disk cache GetAsync, ignore _Lock keys on …
Browse files Browse the repository at this point in the history
…Init() (#529)

* Ignore keys in keys.dat ending in _Lock on Init()

* Clear _Lock key when exception is thrown by dataRetriever()

* Remove redundant Exception vars
  • Loading branch information
dplarina authored Apr 17, 2024
1 parent 914d7e8 commit 3f6835c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 24 deletions.
39 changes: 24 additions & 15 deletions src/EasyCaching.Disk/DefaultDiskCachingProvider.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using Microsoft.Extensions.Logging;

public partial class DefaultDiskCachingProvider : EasyCachingAbstractProvider
{
{
public override async Task<bool> BaseExistsAsync(string cacheKey, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
Expand Down Expand Up @@ -38,7 +38,7 @@ public override Task BaseFlushAsync(CancellationToken cancellationToken = defaul
_cacheKeysMap.Clear();

return Task.CompletedTask;
}
}

public override async Task<IDictionary<string, CacheValue<T>>> BaseGetAllAsync<T>(IEnumerable<string> cacheKeys, CancellationToken cancellationToken = default)
{
Expand Down Expand Up @@ -133,20 +133,29 @@ public override async Task<CacheValue<T>> BaseGetAsync<T>(string cacheKey, Func<
return await GetAsync(cacheKey, dataRetriever, expiration, cancellationToken);
}

var res = await dataRetriever();

if (res != null || _options.CacheNulls)
try
{
var res = await dataRetriever();

if (res != null || _options.CacheNulls)
{
await SetAsync(cacheKey, res, expiration, cancellationToken);
//remove mutex key
_cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _);
return new CacheValue<T>(res, true);
}
else
{
}
else
{
//remove mutex key
_cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _);
return CacheValue<T>.NoValue;
}
}
catch
{
//remove mutex key
_cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _);
throw;
}
}

Expand Down Expand Up @@ -239,7 +248,7 @@ public override async Task<CacheValue<T>> BaseGetAsync<T>(string cacheKey, Cance
return CacheValue<T>.NoValue;
}
}

public override async Task<IDictionary<string, CacheValue<T>>> BaseGetByPrefixAsync<T>(string prefix, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix));
Expand Down Expand Up @@ -286,7 +295,7 @@ public override async Task<IDictionary<string, CacheValue<T>>> BaseGetByPrefixAs

return dict;
}

public override async Task<TimeSpan> BaseGetExpirationAsync(string cacheKey, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
Expand All @@ -301,8 +310,8 @@ public override async Task<TimeSpan> BaseGetExpirationAsync(string cacheKey, Can
var cached = await GetDiskCacheValueAsync(path, cancellationToken);

return DateTimeOffset.FromUnixTimeMilliseconds((long)cached.Expiration).Subtract(DateTimeOffset.UtcNow);
}
}

public override Task BaseRemoveAllAsync(IEnumerable<string> cacheKeys, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNullAndCountGTZero(cacheKeys, nameof(cacheKeys));
Expand Down Expand Up @@ -373,7 +382,7 @@ public override Task BaseRemoveByPatternAsync(string pattern, CancellationToken

var searchPattern = this.ProcessSearchKeyPattern(pattern);
var searchKey = this.HandleSearchKeyPattern(pattern);

var list = _cacheKeysMap.Where(pair => FilterByPattern(pair.Key,searchKey, searchPattern)).Select(x => x.Key).ToList();

foreach (var item in list)
Expand All @@ -388,7 +397,7 @@ public override Task BaseRemoveByPatternAsync(string pattern, CancellationToken

return Task.CompletedTask;
}

public override async Task BaseSetAllAsync<T>(IDictionary<string, T> values, TimeSpan expiration, CancellationToken cancellationToken = default)
{
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
Expand Down Expand Up @@ -462,7 +471,7 @@ public override async Task<bool> BaseTrySetAsync<T>(string cacheKey, T cacheValu
return true;
}
}

private async Task<DiskCacheValue> GetDiskCacheValueAsync(string path, CancellationToken cancellationToken = default)
{
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
Expand Down
30 changes: 21 additions & 9 deletions src/EasyCaching.Disk/DefaultDiskCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ private void InitCacheKey()
string line;
while ((line = reader.ReadLine()) != null)
{
if (!line.EndsWith("_Lock", StringComparison.Ordinal))
{
_cacheKeysMap.TryAdd(line, GetMd5Str(line));
}
}
}
}
Expand Down Expand Up @@ -241,28 +244,37 @@ public override CacheValue<T> BaseGet<T>(string cacheKey, Func<T> dataRetriever,
if (_options.EnableLogging)
_logger?.LogInformation($"Cache Missed : cachekey = {cacheKey}");

// TODO: how to add mutex key here
if (!_cacheKeysMap.TryAdd($"{cacheKey}_Lock", "1"))
try
{
// TODO: how to add mutex key here
if (!_cacheKeysMap.TryAdd($"{cacheKey}_Lock", "1"))
{
System.Threading.Thread.Sleep(_options.SleepMs);
return Get(cacheKey, dataRetriever, expiration);
}
}

var res = dataRetriever();
var res = dataRetriever();

if (res != null || _options.CacheNulls)
{
if (res != null || _options.CacheNulls)
{
Set(cacheKey, res, expiration);
// remove mutex key
_cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _);

return new CacheValue<T>(res, true);
}
else
{
}
else
{
// remove mutex key
_cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _);
return CacheValue<T>.NoValue;
}
}
catch
{
// remove mutex key
_cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _);
throw;
}
}

Expand Down

0 comments on commit 3f6835c

Please sign in to comment.