🐛 Fix the usage counting

This commit is contained in:
2026-01-13 23:53:35 +08:00
parent 065b86403a
commit ab70816a07

View File

@@ -31,44 +31,46 @@ public class UsageService(AppDatabase db)
{ {
var now = SystemClock.Instance.GetCurrentInstant(); var now = SystemClock.Instance.GetCurrentInstant();
var poolUsages = await db.Pools var replicaData = await db.FileReplicas
.Select(p => new UsageDetails .Where(r => r.Status == SnFileReplicaStatus.Available)
{ .Where(r => r.PoolId.HasValue)
PoolId = p.Id, .Join(
PoolName = p.Name, db.Files.Where(f => f.AccountId == accountId)
UsageBytes = db.Files
.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle) .Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now) .Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now),
.SelectMany(f => f.Object!.FileReplicas r => r.ObjectId,
.Where(r => r.PoolId == p.Id && r.Status == SnFileReplicaStatus.Available)) f => f.Id,
.Join(db.FileObjects, (r, f) => new { r.PoolId, r.ObjectId }
r => r.ObjectId, )
o => o.Id, .Join(
(r, o) => o.Size) db.FileObjects,
.DefaultIfEmpty(0L) x => x.ObjectId,
.Sum(), o => o.Id,
Cost = db.Files (x, o) => new { x.PoolId, o.Size }
.Where(f => f.AccountId == accountId) )
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == p.Id && r.Status == SnFileReplicaStatus.Available))
.Join(db.FileObjects,
r => r.ObjectId,
o => o.Id,
(r, o) => new { Size = o.Size, Multiplier = p.BillingConfig.CostMultiplier ?? 1.0 })
.Sum(x => x.Size * x.Multiplier) / 1024.0 / 1024.0,
FileCount = db.Files
.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == p.Id && r.Status == SnFileReplicaStatus.Available))
.Count()
})
.ToListAsync(); .ToListAsync();
var poolUsages = replicaData
.GroupBy(r => r.PoolId!.Value)
.Select(g =>
{
var poolId = g.Key;
var pool = db.Pools.Local.FirstOrDefault(p => p.Id == poolId)
?? db.Pools.Find(poolId);
var multiplier = pool?.BillingConfig.CostMultiplier ?? 1.0;
var totalBytes = g.Sum(x => x.Size);
return new UsageDetails
{
PoolId = poolId,
PoolName = pool?.Name ?? "Unknown",
UsageBytes = totalBytes,
Cost = totalBytes * multiplier / 1024.0 / 1024.0,
FileCount = g.Count()
};
})
.ToList();
var totalUsage = poolUsages.Sum(p => p.UsageBytes); var totalUsage = poolUsages.Sum(p => p.UsageBytes);
var totalFileCount = poolUsages.Sum(p => p.FileCount); var totalFileCount = poolUsages.Sum(p => p.FileCount);
@@ -90,22 +92,27 @@ public class UsageService(AppDatabase db)
} }
var now = SystemClock.Instance.GetCurrentInstant(); var now = SystemClock.Instance.GetCurrentInstant();
var replicaQuery = db.Files
.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == poolId && r.Status == SnFileReplicaStatus.Available));
var usageBytes = await replicaQuery var replicaData = await db.FileReplicas
.Join(db.FileObjects, .Where(r => r.PoolId == poolId)
.Where(r => r.Status == SnFileReplicaStatus.Available)
.Join(
db.Files.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now),
r => r.ObjectId, r => r.ObjectId,
o => o.Id, f => f.Id,
(r, o) => o.Size) (r, f) => r.ObjectId
.DefaultIfEmpty(0L) )
.SumAsync(); .Distinct()
.ToListAsync();
var fileCount = await replicaQuery.CountAsync(); var fileCount = replicaData.Count;
var objectIds = replicaData.Distinct().ToList();
var usageBytes = await db.FileObjects
.Where(o => objectIds.Contains(o.Id))
.SumAsync(o => o.Size);
var cost = usageBytes / 1024.0 / 1024.0 * var cost = usageBytes / 1024.0 / 1024.0 *
(pool.BillingConfig.CostMultiplier ?? 1.0); (pool.BillingConfig.CostMultiplier ?? 1.0);