🗃️ Cloud file usage
This commit is contained in:
parent
7f4c756365
commit
2778626b1f
3407
DysonNetwork.Sphere/Migrations/20250528171935_AddCloudFileUsage.Designer.cs
generated
Normal file
3407
DysonNetwork.Sphere/Migrations/20250528171935_AddCloudFileUsage.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddCloudFileUsage : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "usage",
|
||||||
|
table: "files",
|
||||||
|
type: "character varying(1024)",
|
||||||
|
maxLength: 1024,
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "usage",
|
||||||
|
table: "files");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2296,6 +2296,11 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(128)")
|
.HasColumnType("character varying(128)")
|
||||||
.HasColumnName("uploaded_to");
|
.HasColumnName("uploaded_to");
|
||||||
|
|
||||||
|
b.Property<string>("Usage")
|
||||||
|
.HasMaxLength(1024)
|
||||||
|
.HasColumnType("character varying(1024)")
|
||||||
|
.HasColumnName("usage");
|
||||||
|
|
||||||
b.Property<int>("UsedCount")
|
b.Property<int>("UsedCount")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("used_count");
|
.HasColumnName("used_count");
|
||||||
|
@ -20,7 +20,7 @@ public class FileService(
|
|||||||
ICacheService cache
|
ICacheService cache
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
private const string CacheKeyPrefix = "cloudfile_";
|
private const string CacheKeyPrefix = "file:";
|
||||||
private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(15);
|
private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(15);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -318,6 +318,7 @@ public class FileService(
|
|||||||
|
|
||||||
db.Remove(file);
|
db.Remove(file);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
await _PurgeCacheAsync(file.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteFileDataAsync(CloudFile file)
|
public async Task DeleteFileDataAsync(CloudFile file)
|
||||||
@ -388,6 +389,8 @@ public class FileService(
|
|||||||
b => b.UsedCount + delta
|
b => b.UsedCount + delta
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await _PurgeCacheAsync(file.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MarkUsageRangeAsync(ICollection<CloudFile> files, int delta)
|
public async Task MarkUsageRangeAsync(ICollection<CloudFile> files, int delta)
|
||||||
@ -399,6 +402,8 @@ public class FileService(
|
|||||||
b => b.UsedCount + delta
|
b => b.UsedCount + delta
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await _PurgeCacheRangeAsync(files.Select(x => x.Id).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -413,6 +418,55 @@ public class FileService(
|
|||||||
: _ => null
|
: _ => null
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await _PurgeCacheRangeAsync(files.Select(x => x.Id).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetUsageAsync(CloudFile file, string? usage)
|
||||||
|
{
|
||||||
|
await db.Files.Where(o => o.Id == file.Id)
|
||||||
|
.ExecuteUpdateAsync(setter => setter.SetProperty(
|
||||||
|
b => b.Usage,
|
||||||
|
_ => usage
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
await _PurgeCacheAsync(file.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetUsageRangeAsync(ICollection<CloudFile> files, string? usage)
|
||||||
|
{
|
||||||
|
var ids = files.Select(f => f.Id).ToArray();
|
||||||
|
await db.Files.Where(o => ids.Contains(o.Id))
|
||||||
|
.ExecuteUpdateAsync(setter => setter.SetProperty(
|
||||||
|
b => b.Usage,
|
||||||
|
_ => usage
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
await _PurgeCacheRangeAsync(files.Select(x => x.Id).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(ICollection<CloudFile> current, ICollection<CloudFile> added, ICollection<CloudFile> removed)>
|
||||||
|
DiffAndSetUsageAsync(
|
||||||
|
ICollection<string>? newFileIds,
|
||||||
|
string? usage,
|
||||||
|
ICollection<CloudFile>? previousFiles = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (newFileIds == null) return ([], [], previousFiles ?? []);
|
||||||
|
|
||||||
|
var records = await db.Files.Where(f => newFileIds.Contains(f.Id)).ToListAsync();
|
||||||
|
var previous = previousFiles?.ToDictionary(f => f.Id) ?? new Dictionary<string, CloudFile>();
|
||||||
|
var current = records.ToDictionary(f => f.Id);
|
||||||
|
|
||||||
|
var added = current.Keys.Except(previous.Keys).Select(id => current[id]).ToList();
|
||||||
|
var removed = previous.Keys.Except(current.Keys).Select(id => previous[id]).ToList();
|
||||||
|
|
||||||
|
if (added.Count > 0) await SetUsageRangeAsync(added, usage);
|
||||||
|
if (removed.Count > 0) await SetUsageRangeAsync(removed, null);
|
||||||
|
|
||||||
|
return (newFileIds.Select(id => current[id]).ToList(), added, removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(ICollection<CloudFile> current, ICollection<CloudFile> added, ICollection<CloudFile> removed)>
|
public async Task<(ICollection<CloudFile> current, ICollection<CloudFile> added, ICollection<CloudFile> removed)>
|
||||||
@ -457,6 +511,20 @@ public class FileService(
|
|||||||
|
|
||||||
return (newFileIds.Select(id => current[id]).ToList(), added, removed);
|
return (newFileIds.Select(id => current[id]).ToList(), added, removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this helper method to purge the cache for a specific file
|
||||||
|
private async Task _PurgeCacheAsync(string fileId)
|
||||||
|
{
|
||||||
|
var cacheKey = $"{CacheKeyPrefix}{fileId}";
|
||||||
|
await cache.RemoveAsync(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add this helper method to purge cache for multiple files
|
||||||
|
private async Task _PurgeCacheRangeAsync(ICollection<string> fileIds)
|
||||||
|
{
|
||||||
|
var tasks = fileIds.Select(_PurgeCacheAsync);
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CloudFileUnusedRecyclingJob(AppDatabase db, FileService fs, ILogger<CloudFileUnusedRecyclingJob> logger)
|
public class CloudFileUnusedRecyclingJob(AppDatabase db, FileService fs, ILogger<CloudFileUnusedRecyclingJob> logger)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user