♻️ Optimization in file uploading
This commit is contained in:
@ -1,11 +1,23 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Sphere.Permission;
|
||||
|
||||
public class PermissionService(AppDatabase db)
|
||||
public class PermissionService(
|
||||
AppDatabase db,
|
||||
IMemoryCache cache,
|
||||
ILogger<PermissionService> logger)
|
||||
{
|
||||
private static readonly TimeSpan CacheExpiration = TimeSpan.FromMinutes(1);
|
||||
|
||||
private string GetPermissionCacheKey(string actor, string area, string key) =>
|
||||
$"perm:{actor}:{area}:{key}";
|
||||
|
||||
private string GetGroupsCacheKey(string actor) =>
|
||||
$"perm_groups:{actor}";
|
||||
|
||||
public async Task<bool> HasPermissionAsync(string actor, string area, string key)
|
||||
{
|
||||
var value = await GetPermissionAsync<bool>(actor, area, key);
|
||||
@ -14,13 +26,27 @@ public class PermissionService(AppDatabase db)
|
||||
|
||||
public async Task<T?> GetPermissionAsync<T>(string actor, string area, string key)
|
||||
{
|
||||
var cacheKey = GetPermissionCacheKey(actor, area, key);
|
||||
|
||||
if (cache.TryGetValue<T>(cacheKey, out var cachedValue))
|
||||
{
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
var groupsId = await db.PermissionGroupMembers
|
||||
.Where(n => n.Actor == actor)
|
||||
.Where(n => n.ExpiredAt == null || n.ExpiredAt < now)
|
||||
.Where(n => n.AffectedAt == null || n.AffectedAt >= now)
|
||||
.Select(e => e.GroupId)
|
||||
.ToListAsync();
|
||||
var groupsKey = GetGroupsCacheKey(actor);
|
||||
|
||||
var groupsId = await cache.GetOrCreateAsync(groupsKey, async entry =>
|
||||
{
|
||||
entry.AbsoluteExpirationRelativeToNow = CacheExpiration;
|
||||
return await db.PermissionGroupMembers
|
||||
.Where(n => n.Actor == actor)
|
||||
.Where(n => n.ExpiredAt == null || n.ExpiredAt < now)
|
||||
.Where(n => n.AffectedAt == null || n.AffectedAt >= now)
|
||||
.Select(e => e.GroupId)
|
||||
.ToListAsync();
|
||||
});
|
||||
|
||||
var permission = await db.PermissionNodes
|
||||
.Where(n => n.GroupId == null || groupsId.Contains(n.GroupId.Value))
|
||||
.Where(n => (n.Key == key || n.Key == "*") && (n.GroupId != null || n.Actor == actor) && n.Area == area)
|
||||
@ -28,7 +54,11 @@ public class PermissionService(AppDatabase db)
|
||||
.Where(n => n.AffectedAt == null || n.AffectedAt >= now)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return permission is not null ? _DeserializePermissionValue<T>(permission.Value) : default;
|
||||
var result = permission is not null ? _DeserializePermissionValue<T>(permission.Value) : default;
|
||||
|
||||
cache.Set(cacheKey, result, CacheExpiration);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<PermissionNode> AddPermissionNode<T>(
|
||||
@ -55,6 +85,9 @@ public class PermissionService(AppDatabase db)
|
||||
db.PermissionNodes.Add(node);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
// Invalidate related caches
|
||||
InvalidatePermissionCache(actor, area, key);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -85,6 +118,10 @@ public class PermissionService(AppDatabase db)
|
||||
db.PermissionNodes.Add(node);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
// Invalidate related caches
|
||||
InvalidatePermissionCache(actor, area, key);
|
||||
cache.Remove(GetGroupsCacheKey(actor));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -95,6 +132,9 @@ public class PermissionService(AppDatabase db)
|
||||
.FirstOrDefaultAsync();
|
||||
if (node is not null) db.PermissionNodes.Remove(node);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
// Invalidate cache
|
||||
InvalidatePermissionCache(actor, area, key);
|
||||
}
|
||||
|
||||
public async Task RemovePermissionNodeFromGroup<T>(PermissionGroup group, string actor, string area, string key)
|
||||
@ -106,6 +146,16 @@ public class PermissionService(AppDatabase db)
|
||||
if (node is null) return;
|
||||
db.PermissionNodes.Remove(node);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
// Invalidate caches
|
||||
InvalidatePermissionCache(actor, area, key);
|
||||
cache.Remove(GetGroupsCacheKey(actor));
|
||||
}
|
||||
|
||||
private void InvalidatePermissionCache(string actor, string area, string key)
|
||||
{
|
||||
var cacheKey = GetPermissionCacheKey(actor, area, key);
|
||||
cache.Remove(cacheKey);
|
||||
}
|
||||
|
||||
private static T? _DeserializePermissionValue<T>(JsonDocument json)
|
||||
|
Reference in New Issue
Block a user