65 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Microsoft.EntityFrameworkCore;
 | |
| using NodaTime;
 | |
| using Quartz;
 | |
| 
 | |
| namespace DysonNetwork.Drive.Storage;
 | |
| 
 | |
| /// <summary>
 | |
| /// Job responsible for cleaning up expired file references
 | |
| /// </summary>
 | |
| public class FileExpirationJob(AppDatabase db, FileService fileService, ILogger<FileExpirationJob> logger) : IJob
 | |
| {
 | |
|     public async Task Execute(IJobExecutionContext context)
 | |
|     {        
 | |
|         var now = SystemClock.Instance.GetCurrentInstant();
 | |
|         logger.LogInformation("Running file reference expiration job at {now}", now);
 | |
| 
 | |
|         // Find all expired references
 | |
|         var expiredReferences = await db.FileReferences
 | |
|             .Where(r => r.ExpiredAt < now && r.ExpiredAt != null)
 | |
|             .ToListAsync();
 | |
| 
 | |
|         if (!expiredReferences.Any())
 | |
|         {
 | |
|             logger.LogInformation("No expired file references found");
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         logger.LogInformation("Found {count} expired file references", expiredReferences.Count);
 | |
| 
 | |
|         // Get unique file IDs
 | |
|         var fileIds = expiredReferences.Select(r => r.FileId).Distinct().ToList();
 | |
|         var filesAndReferenceCount = new Dictionary<string, int>();
 | |
| 
 | |
|         // Delete expired references
 | |
|         db.FileReferences.RemoveRange(expiredReferences);
 | |
|         await db.SaveChangesAsync();
 | |
| 
 | |
|         // Check remaining references for each file
 | |
|         foreach (var fileId in fileIds)
 | |
|         {            
 | |
|             var remainingReferences = await db.FileReferences
 | |
|                 .Where(r => r.FileId == fileId)
 | |
|                 .CountAsync();
 | |
| 
 | |
|             filesAndReferenceCount[fileId] = remainingReferences;
 | |
| 
 | |
|             // If no references remain, delete the file
 | |
|             if (remainingReferences == 0)
 | |
|             {
 | |
|                 var file = await db.Files.FirstOrDefaultAsync(f => f.Id == fileId);
 | |
|                 if (file == null) continue;
 | |
|                 logger.LogInformation("Deleting file {fileId} as all references have expired", fileId);
 | |
|                 await fileService.DeleteFileAsync(file);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // Just purge the cache
 | |
|                 await fileService._PurgeCacheAsync(fileId);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         logger.LogInformation("Completed file reference expiration job");
 | |
|     }
 | |
| }
 |