2022-01-19 16:25:10 +00:00
namespace ASC.Data.Backup.Services ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
[Singletone]
internal sealed class BackupCleanerService : IHostedService , IDisposable
{
private Timer _timer ;
private readonly ILog _logger ;
private readonly TimeSpan _period ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
private readonly IServiceScopeFactory _scopeFactory ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
public BackupCleanerService (
ConfigurationExtension configuration ,
IOptionsMonitor < ILog > options ,
IServiceScopeFactory scopeFactory )
{
_scopeFactory = scopeFactory ;
_logger = options . CurrentValue ;
_period = configuration . GetSetting < BackupSettings > ( "backup" ) . Cleaner . Period ;
}
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
public Task StartAsync ( CancellationToken cancellationToken )
2022-01-17 11:15:46 +00:00
{
2022-01-19 16:25:10 +00:00
_logger . Info ( "starting backup cleaner service..." ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
_timer = new Timer ( DeleteExpiredBackups , null , TimeSpan . Zero , _period ) ;
2022-01-17 15:03:28 +00:00
2022-01-19 16:25:10 +00:00
_logger . Info ( "backup cleaner service started" ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
return Task . CompletedTask ;
}
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
public void DeleteExpiredBackups ( object state )
{
using var serviceScope = _scopeFactory . CreateScope ( ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
var backupRepository = serviceScope . ServiceProvider . GetRequiredService < BackupRepository > ( ) ;
var backupStorageFactory = serviceScope . ServiceProvider . GetRequiredService < BackupStorageFactory > ( ) ;
2022-01-18 16:04:35 +00:00
2022-01-19 16:25:10 +00:00
_logger . Debug ( "started to clean expired backups" ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
var backupsToRemove = backupRepository . GetExpiredBackupRecords ( ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
_logger . DebugFormat ( "found {0} backups which are expired" , backupsToRemove . Count ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
foreach ( var scheduledBackups in backupRepository . GetScheduledBackupRecords ( ) . GroupBy ( r = > r . TenantId ) )
{
var schedule = backupRepository . GetBackupSchedule ( scheduledBackups . Key ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
if ( schedule ! = null )
2022-01-17 11:15:46 +00:00
{
2022-01-19 16:25:10 +00:00
var scheduledBackupsToRemove = scheduledBackups . OrderByDescending ( r = > r . CreatedOn ) . Skip ( schedule . BackupsStored ) . ToList ( ) ;
if ( scheduledBackupsToRemove . Any ( ) )
2022-01-17 11:15:46 +00:00
{
2022-01-19 16:25:10 +00:00
_logger . DebugFormat ( "only last {0} scheduled backup records are to keep for tenant {1} so {2} records must be removed" , schedule . BackupsStored , schedule . TenantId , scheduledBackupsToRemove . Count ) ;
backupsToRemove . AddRange ( scheduledBackupsToRemove ) ;
2022-01-17 11:15:46 +00:00
}
}
2022-01-19 16:25:10 +00:00
else
{
backupsToRemove . AddRange ( scheduledBackups ) ;
}
}
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
foreach ( var backupRecord in backupsToRemove )
{
try
2022-01-17 11:15:46 +00:00
{
2022-01-19 16:25:10 +00:00
var backupStorage = backupStorageFactory . GetBackupStorage ( backupRecord ) ;
if ( backupStorage = = null ) continue ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
backupStorage . Delete ( backupRecord . StoragePath ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
backupRepository . DeleteBackupRecord ( backupRecord . Id ) ;
}
catch ( ProviderInfoArgumentException error )
{
_logger . Warn ( "can't remove backup record " + backupRecord . Id , error ) ;
2022-01-18 16:04:35 +00:00
2022-01-19 16:25:10 +00:00
if ( DateTime . UtcNow > backupRecord . CreatedOn . AddMonths ( 6 ) )
2022-01-17 11:15:46 +00:00
{
2022-01-19 16:25:10 +00:00
backupRepository . DeleteBackupRecord ( backupRecord . Id ) ;
2022-01-17 11:15:46 +00:00
}
}
2022-01-19 16:25:10 +00:00
catch ( Exception error )
{
_logger . Warn ( "can't remove backup record: " + backupRecord . Id , error ) ;
}
2022-01-17 11:15:46 +00:00
}
2022-01-19 16:25:10 +00:00
}
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
public Task StopAsync ( CancellationToken cancellationToken )
{
_logger . Info ( "stopping backup cleaner service..." ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
_timer ? . Change ( Timeout . Infinite , 0 ) ;
_logger . Info ( "backup cleaner service stopped" ) ;
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
return Task . CompletedTask ;
}
2022-01-17 11:15:46 +00:00
2022-01-19 16:25:10 +00:00
public void Dispose ( )
{
_timer ? . Dispose ( ) ;
2022-01-17 11:15:46 +00:00
}
2022-01-19 16:25:10 +00:00
}