diff --git a/src/EasyCaching.Disk/DefaultDiskCachingProvider.Async.cs b/src/EasyCaching.Disk/DefaultDiskCachingProvider.Async.cs index b7908e83..1ef9661b 100644 --- a/src/EasyCaching.Disk/DefaultDiskCachingProvider.Async.cs +++ b/src/EasyCaching.Disk/DefaultDiskCachingProvider.Async.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging; public partial class DefaultDiskCachingProvider : EasyCachingAbstractProvider - { + { public override async Task BaseExistsAsync(string cacheKey, CancellationToken cancellationToken = default) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); @@ -38,7 +38,7 @@ public override Task BaseFlushAsync(CancellationToken cancellationToken = defaul _cacheKeysMap.Clear(); return Task.CompletedTask; - } + } public override async Task>> BaseGetAllAsync(IEnumerable cacheKeys, CancellationToken cancellationToken = default) { @@ -133,20 +133,29 @@ public override async Task> BaseGetAsync(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(res, true); - } - else - { + } + else + { //remove mutex key _cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _); return CacheValue.NoValue; + } + } + catch + { + //remove mutex key + _cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _); + throw; } } @@ -239,7 +248,7 @@ public override async Task> BaseGetAsync(string cacheKey, Cance return CacheValue.NoValue; } } - + public override async Task>> BaseGetByPrefixAsync(string prefix, CancellationToken cancellationToken = default) { ArgumentCheck.NotNullOrWhiteSpace(prefix, nameof(prefix)); @@ -286,7 +295,7 @@ public override async Task>> BaseGetByPrefixAs return dict; } - + public override async Task BaseGetExpirationAsync(string cacheKey, CancellationToken cancellationToken = default) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); @@ -301,8 +310,8 @@ public override async Task BaseGetExpirationAsync(string cacheKey, Can var cached = await GetDiskCacheValueAsync(path, cancellationToken); return DateTimeOffset.FromUnixTimeMilliseconds((long)cached.Expiration).Subtract(DateTimeOffset.UtcNow); - } - + } + public override Task BaseRemoveAllAsync(IEnumerable cacheKeys, CancellationToken cancellationToken = default) { ArgumentCheck.NotNullAndCountGTZero(cacheKeys, nameof(cacheKeys)); @@ -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) @@ -388,7 +397,7 @@ public override Task BaseRemoveByPatternAsync(string pattern, CancellationToken return Task.CompletedTask; } - + public override async Task BaseSetAllAsync(IDictionary values, TimeSpan expiration, CancellationToken cancellationToken = default) { ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration)); @@ -462,7 +471,7 @@ public override async Task BaseTrySetAsync(string cacheKey, T cacheValu return true; } } - + private async Task GetDiskCacheValueAsync(string path, CancellationToken cancellationToken = default) { using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) diff --git a/src/EasyCaching.Disk/DefaultDiskCachingProvider.cs b/src/EasyCaching.Disk/DefaultDiskCachingProvider.cs index a3a08b5b..558dc40b 100644 --- a/src/EasyCaching.Disk/DefaultDiskCachingProvider.cs +++ b/src/EasyCaching.Disk/DefaultDiskCachingProvider.cs @@ -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)); + } } } } @@ -241,28 +244,37 @@ public override CacheValue BaseGet(string cacheKey, Func 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(res, true); - } - else - { + } + else + { // remove mutex key _cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _); return CacheValue.NoValue; + } + } + catch + { + // remove mutex key + _cacheKeysMap.TryRemove($"{cacheKey}_Lock", out _); + throw; } }