Skip to content

Commit

Permalink
Update DataCleanupService to also remove expired recordings.
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbound committed Jul 5, 2023
1 parent eff8985 commit 066a1bd
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 34 deletions.
107 changes: 79 additions & 28 deletions Server/Services/DataCleanupService.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,113 @@
using Microsoft.Build.Framework;
using Immense.RemoteControl.Shared.Services;
using Microsoft.Build.Framework;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Client;
using Remotely.Server.Services.RcImplementations;
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;

namespace Remotely.Server.Services
{
public class DataCleanupService : IHostedService, IDisposable
public class DataCleanupService : BackgroundService, IDisposable
{
private readonly ILogger<DataCleanupService> _logger;

private readonly IServiceProvider _services;

private System.Timers.Timer _cleanupTimer = new(TimeSpan.FromDays(1));

private readonly IServiceScopeFactory _scopeFactory;
private readonly ISystemTime _systemTime;
private readonly IApplicationConfig _appConfig;

public DataCleanupService(
IServiceProvider serviceProvider,
IServiceScopeFactory scopeFactory,
ISystemTime systemTime,
IApplicationConfig appConfig,
ILogger<DataCleanupService> logger)
{
_services = serviceProvider;
_scopeFactory = scopeFactory;
_systemTime = systemTime;
_appConfig = appConfig;
_logger = logger;

_cleanupTimer.Elapsed += CleanupTimer_Elapsed;
}
public void Dispose()

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_cleanupTimer?.Dispose();
GC.SuppressFinalize(this);
await Task.Yield();

await PerformCleanup();

using var timer = new PeriodicTimer(TimeSpan.FromDays(1));

while (!stoppingToken.IsCancellationRequested)
{
try
{
_ = await timer.WaitForNextTickAsync(stoppingToken);
await PerformCleanup();
}
catch (OperationCanceledException)
{
_logger.LogInformation("Application is shutting down. Stopping data cleanup service.");
}

}
}

public Task StartAsync(CancellationToken cancellationToken)
private async Task PerformCleanup()
{
_cleanupTimer.Start();
return Task.CompletedTask;
try
{
await RemoveExpiredDbRecords();
await RemoveExpiredRecordings();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error during data cleanup.");
}
}

public Task StopAsync(CancellationToken cancellationToken)
private async Task RemoveExpiredDbRecords()
{
_cleanupTimer.Stop();
_cleanupTimer.Dispose();
return Task.CompletedTask;
using var scope = _scopeFactory.CreateScope();
var dataService = scope.ServiceProvider.GetRequiredService<IDataService>();
await dataService.CleanupOldRecords();
}

private void CleanupTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
private Task RemoveExpiredRecordings()
{
try
if (!Directory.Exists(SessionRecordingSink.RecordingsDirectory))
{
using var scope = _services.CreateScope();
var dataService = scope.ServiceProvider.GetRequiredService<IDataService>();
dataService.CleanupOldRecords();
return Task.CompletedTask;
}
catch (Exception ex)

var expirationDate = _systemTime.Now.UtcDateTime - TimeSpan.FromDays(_appConfig.DataRetentionInDays);

var files = Directory
.GetFiles(
SessionRecordingSink.RecordingsDirectory,
"*.webm",
SearchOption.AllDirectories)
.Select(x => new FileInfo(x))
.Where(x => x.CreationTimeUtc < expirationDate)
.ToList();

foreach (var file in files)
{
_logger.LogError(ex, "Error during data cleanup.");
try
{
file.Delete();
_logger.LogInformation("Expired recording deleted: {file}", file.FullName);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while deleting expired recording: {file}", file);
}
}

return Task.CompletedTask;
}
}
}
11 changes: 6 additions & 5 deletions Server/Services/DataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public interface IDataService

void ChangeUserIsAdmin(string organizationID, string targetUserID, bool isAdmin);

void CleanupOldRecords();
Task CleanupOldRecords();

Task<ApiToken> CreateApiToken(string userName, string tokenName, string secretHash);

Expand Down Expand Up @@ -623,19 +623,20 @@ public void ChangeUserIsAdmin(string organizationID, string targetUserID, bool i
}
}

public void CleanupOldRecords()
public async Task CleanupOldRecords()
{
using var dbContext = _appDbFactory.GetContext();

if (_appConfig.DataRetentionInDays > -1)
{
var expirationDate = DateTimeOffset.Now - TimeSpan.FromDays(_appConfig.DataRetentionInDays);

var scriptRuns = dbContext.ScriptRuns
var scriptRuns = await dbContext.ScriptRuns
.Include(x => x.Results)
.Include(x => x.Devices)
.Include(x => x.DevicesCompleted)
.Where(x => x.RunAt < expirationDate);
.Where(x => x.RunAt < expirationDate)
.ToArrayAsync();

foreach (var run in scriptRuns)
{
Expand All @@ -656,7 +657,7 @@ public void CleanupOldRecords()

dbContext.RemoveRange(sharedFiles);

dbContext.SaveChanges();
await dbContext.SaveChangesAsync();
}
}

Expand Down
2 changes: 1 addition & 1 deletion Server/Services/RcImplementations/SessionRecordingSink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public SessionRecordingSink(ILogger<SessionRecordingSink> logger)
_logger = logger;
}

private static string RecordingsDirectory
public static string RecordingsDirectory
{
get
{
Expand Down

0 comments on commit 066a1bd

Please sign in to comment.