Skip to content
This repository was archived by the owner on Sep 6, 2023. It is now read-only.

Commit f56ce58

Browse files
Merge pull request #795 from ronaldbarendse/fix-cachetrimmer
Fix race condition in DiskCache trimmer causing DirectoryNotFoundException
2 parents 58f6475 + 8498d14 commit f56ce58

File tree

1 file changed

+35
-37
lines changed

1 file changed

+35
-37
lines changed

src/ImageProcessor.Web/Caching/DiskCache.cs

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -211,64 +211,62 @@ public override Task TrimCacheAsync()
211211

212212
this.ScheduleCacheTrimmer(token =>
213213
{
214-
string rootDirectory = Path.GetDirectoryName(this.CachedPath);
215-
214+
var rootDirectory = Path.GetDirectoryName(this.CachedPath);
216215
if (rootDirectory != null)
217216
{
218-
// Jump up to the parent branch to clean through the cache.
219-
// UNC folders can throw exceptions if the file doesn't exist.
220-
IEnumerable<string> directories = SafeEnumerateDirectories(validatedAbsoluteCachePath).Reverse();
221-
217+
// Jump up to the parent branch to clean through the cache
218+
// UNC folders can throw exceptions if the file doesn't exist
219+
var directories = SafeEnumerateDirectories(validatedAbsoluteCachePath).Reverse().ToList();
222220
foreach (string directory in directories)
223221
{
224-
if (!Directory.Exists(directory))
225-
{
226-
continue;
227-
}
228-
229222
if (token.IsCancellationRequested)
230223
{
231224
break;
232225
}
233226

234-
IEnumerable<FileInfo> files = Directory.EnumerateFiles(directory)
235-
.Select(f => new FileInfo(f))
236-
.OrderBy(f => f.CreationTimeUtc);
237-
int count = files.Count();
238-
239-
foreach (FileInfo fileInfo in files)
227+
try
240228
{
241-
if (token.IsCancellationRequested)
242-
{
243-
break;
244-
}
245-
246-
try
229+
var files = Directory.EnumerateFiles(directory).Select(f => new FileInfo(f)).OrderBy(f => f.CreationTimeUtc).ToList();
230+
var count = files.Count;
231+
foreach (var fileInfo in files)
247232
{
248-
// If the group count is equal to the max count minus 1 then we know we
249-
// have reduced the number of items below the maximum allowed.
250-
// We'll cleanup any orphaned expired files though.
251-
if (!this.IsExpired(fileInfo.CreationTimeUtc) && count <= MaxFilesCount - 1)
233+
if (token.IsCancellationRequested)
252234
{
253235
break;
254236
}
255237

256-
// Remove from the cache and delete each CachedImage.
257-
CacheIndexer.Remove(fileInfo.Name);
258-
fileInfo.Delete();
259-
count--;
260-
}
261-
catch (Exception ex)
262-
{
263-
// Log it but skip to the next file.
264-
ImageProcessorBootstrapper.Instance.Logger.Log<DiskCache>($"Unable to clean cached file: {fileInfo.FullName}, {ex.Message}");
238+
try
239+
{
240+
// If the group count is equal to the max count minus 1 then we know we have reduced the number of items below the maximum allowed
241+
// We'll cleanup any orphaned expired files though
242+
if (!this.IsExpired(fileInfo.CreationTimeUtc) && count <= MaxFilesCount - 1)
243+
{
244+
break;
245+
}
246+
247+
// Remove from the cache and delete each CachedImage
248+
CacheIndexer.Remove(fileInfo.Name);
249+
fileInfo.Delete();
250+
count--;
251+
}
252+
catch (Exception ex)
253+
{
254+
// Log it but skip to the next file
255+
ImageProcessorBootstrapper.Instance.Logger.Log<DiskCache>($"Unable to clean cached file: {fileInfo.FullName}, {ex.Message}");
256+
}
265257
}
266258
}
259+
catch (Exception ex)
260+
{
261+
// Log it but skip to the next directory
262+
ImageProcessorBootstrapper.Instance.Logger.Log<DiskCache>($"Unable to clean cached directory: {directory}, {ex.Message}");
263+
}
267264

268-
// If the directory is empty of files delete it to remove the FCN.
265+
// If the directory is empty of files delete it to remove the FCN
269266
this.RecursivelyDeleteEmptyDirectories(directory, validatedAbsoluteCachePath, token);
270267
}
271268
}
269+
272270
return Task.FromResult(0);
273271
});
274272

0 commit comments

Comments
 (0)