Moves temp file cleanup to a background task

This commit is contained in:
Shannon
2019-09-18 22:03:31 +10:00
parent 87d0937389
commit 5cfdfd6e9c
6 changed files with 94 additions and 43 deletions

View File

@@ -104,24 +104,6 @@ namespace Umbraco.Web.Editors
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, $"Error when trying to move {currentFile} to {newFilePath}", ex);
}
// Now remove all old files so that the temp folder(s) never grow
// Anything older than one day gets deleted
var tempFiles = Directory.GetFiles(IOHelper.MapPath(SystemDirectories.TempFileUploads), "*", SearchOption.AllDirectories);
foreach (var tempFile in tempFiles)
{
if (DateTime.UtcNow - File.GetLastWriteTimeUtc(tempFile) > TimeSpan.FromDays(1))
{
try
{
File.Delete(tempFile);
}
catch (Exception ex)
{
Logger.Error<TinyMceController>(ex, "Could not delete temp file {FileName}", tempFile);
}
}
}
return Request.CreateResponse(HttpStatusCode.OK, new { tmpLocation = relativeNewFilePath });
}
}

View File

@@ -1,16 +1,14 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
namespace Umbraco.Web.Scheduling
{
internal class LogScrubber : RecurringTaskBase
{
private readonly IRuntimeState _runtime;

View File

@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
@@ -29,6 +31,7 @@ namespace Umbraco.Web.Scheduling
private BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
private BackgroundTaskRunner<IBackgroundTask> _tasksRunner;
private BackgroundTaskRunner<IBackgroundTask> _scrubberRunner;
private BackgroundTaskRunner<IBackgroundTask> _fileCleanupRunner;
private BackgroundTaskRunner<IBackgroundTask> _healthCheckRunner;
private bool _started;
@@ -58,6 +61,7 @@ namespace Umbraco.Web.Scheduling
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", _logger);
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", _logger);
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", _logger);
_fileCleanupRunner = new BackgroundTaskRunner<IBackgroundTask>("TempFileCleanup", _logger);
_healthCheckRunner = new BackgroundTaskRunner<IBackgroundTask>("HealthCheckNotifier", _logger);
// we will start the whole process when a successful request is made
@@ -93,6 +97,7 @@ namespace Umbraco.Web.Scheduling
tasks.Add(RegisterKeepAlive());
tasks.Add(RegisterScheduledPublishing());
tasks.Add(RegisterLogScrubber(settings));
tasks.Add(RegisterTempFileCleanup());
var healthCheckConfig = Current.Configs.HealthChecks();
if (healthCheckConfig.NotificationSettings.Enabled)
@@ -154,5 +159,17 @@ namespace Umbraco.Web.Scheduling
_scrubberRunner.TryAdd(task);
return task;
}
private IBackgroundTask RegisterTempFileCleanup()
{
// temp file cleanup, will run on all servers - even though file upload should only be handled on the master, this will
// ensure that in the case it happes on replicas that they are cleaned up.
var task = new TempFileCleanup(_fileCleanupRunner, 60000, 3600000 /* 1 hr */,
new[] { new DirectoryInfo(IOHelper.MapPath(SystemDirectories.TempFileUploads)) },
TimeSpan.FromDays(1), //files that are over a day old
_runtime, _logger);
_scrubberRunner.TryAdd(task);
return task;
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Scheduling
{
/// <summary>
/// Used to cleanup temporary file locations
/// </summary>
internal class TempFileCleanup : RecurringTaskBase
{
private readonly DirectoryInfo[] _tempFolders;
private readonly TimeSpan _age;
private readonly IRuntimeState _runtime;
private readonly IProfilingLogger _logger;
public TempFileCleanup(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
IEnumerable<DirectoryInfo> tempFolders, TimeSpan age,
IRuntimeState runtime, IProfilingLogger logger)
: base(runner, delayMilliseconds, periodMilliseconds)
{
//SystemDirectories.TempFileUploads
_tempFolders = tempFolders.ToArray();
_age = age;
_runtime = runtime;
_logger = logger;
}
public override bool PerformRun()
{
// ensure we do not run if not main domain
if (_runtime.IsMainDom == false)
{
_logger.Debug<TempFileCleanup>("Does not run if not MainDom.");
return false; // do NOT repeat, going down
}
foreach (var dir in _tempFolders)
CleanupFolder(dir);
return true; //repeat
}
private void CleanupFolder(DirectoryInfo dir)
{
dir.Refresh(); //in case it's changed during runtime
if (!dir.Exists)
{
_logger.Debug<TempFileCleanup>("The cleanup folder doesn't exist {Folder}", dir.FullName);
}
var files = dir.GetFiles("*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
if (DateTime.UtcNow - file.LastWriteTimeUtc > _age)
{
try
{
file.Delete();
}
catch (Exception ex)
{
_logger.Error<TempFileCleanup>(ex, "Could not delete temp file {FileName}", file.FullName);
}
}
}
}
public override bool IsAsync => false;
}
}

View File

@@ -236,6 +236,7 @@
<Compile Include="Routing\IPublishedRouter.cs" />
<Compile Include="Routing\MediaUrlProviderCollection.cs" />
<Compile Include="Routing\MediaUrlProviderCollectionBuilder.cs" />
<Compile Include="Scheduling\TempFileCleanup.cs" />
<Compile Include="Search\BackgroundIndexRebuilder.cs" />
<Compile Include="Search\ExamineFinalComponent.cs" />
<Compile Include="Search\ExamineFinalComposer.cs" />

View File

@@ -146,28 +146,6 @@ namespace Umbraco.Web.WebApi.Filters
Current.Logger.Warn<FileUploadCleanupFilterAttribute>("The actionExecutedContext.Request.Content is not ObjectContent, it is {RequestObjectType}", actionExecutedContext.Request.Content.GetType());
}
}
//Now remove all old files so that the temp folder(s) never grow
foreach (var tempFolder in tempFolders.Distinct())
{
var files = Directory.GetFiles(tempFolder);
foreach (var file in files)
{
if (DateTime.UtcNow - File.GetLastWriteTimeUtc(file) > TimeSpan.FromDays(1))
{
try
{
File.Delete(file);
}
catch (System.Exception ex)
{
Current.Logger.Error<FileUploadCleanupFilterAttribute>(ex, "Could not delete temp file {FileName}", file);
}
}
}
}
}
}
}